dougong7850 2014-10-23 05:00
浏览 29
已采纳

Golang,如何分享价值-消息还是互斥体?

I've done simple bench mark which one is more efficient among message-passing and locking for shared value.

Firstly, please check code bellow.

package main

import (
    "flag"
    "fmt"
    "math/rand"
    "runtime"
    "sync"
    "time"
)

type Request struct {
    Id      int
    ResChan chan Response
}

type Response struct {
    Id    int
    Value int
}

func main() {
    procNum := flag.Int("proc", 1, "Number of processes to use")
    clientNum := flag.Int("client", 1, "Number of clients")
    mode := flag.String("mode", "message", "message or mutex")
    flag.Parse()

    if *procNum > runtime.NumCPU() {
        *procNum = runtime.NumCPU()
    }

    fmt.Println("proc:", *procNum)
    fmt.Println("client:", *clientNum)
    fmt.Println("mode:", *mode)

    runtime.GOMAXPROCS(*procNum)

    rand.Seed(time.Now().UnixNano())
    var wg sync.WaitGroup

    sharedValue := 0

    start := time.Now()

    if *mode == "message" {
        reqChan := make(chan Request) // increasing channel size does not change the result
        go func() {
            for {
                req := <-reqChan
                sharedValue++
                req.ResChan <- Response{Id: req.Id, Value: sharedValue}
            }
        }()

        for i := 0; i < *clientNum; i++ {
            wg.Add(1)
            go func(index int) {
                defer wg.Done()
                c := make(chan Response)
                defer close(c)
                id := rand.Int()
                reqChan <- Request{Id: id, ResChan: c}
                <-c
            }(i)
        }
    } else if *mode == "mutex" {
        mutex := &sync.Mutex{}

        for i := 0; i < *clientNum; i++ {
            wg.Add(1)
            go func(index int) {
                defer wg.Done()
                mutex.Lock()
                sharedValue++
                mutex.Unlock()
            }(i)
        }
    }

    wg.Wait()
    elapsed := time.Since(start)

    fmt.Println("Elapsed:", elapsed, "value:", sharedValue)
}

As you already noticed, program is relatively simple. In message mode, it increases sharedValue by message passing. In mutex mode, it increases sharedValue by locking.

I've tried to use only one channel for message mode and gave up. I think it may not possible, isn't it?

My computer have 2 Xeon CPUs and each have 6 cores. Because of hyper threading, logically 24 cores are available. Its ram size is 12G.

If I run the program with any number for flags, mutex mode is always faster minimum 2 times(usually 3 times).

Okay, I can understand that managing channels need some amount of cost. Then, if I consider performance only, are there any reason to use channel instead of mutex? Plus, can message-passing cost be ignored with huge size of message?

  • 写回答

3条回答 默认 最新

  • duanmi4379 2014-10-23 05:57
    关注

    if I consider performance only, are there any reason to use channel instead of mutex?

    Not really. The wiki page "Use a sync.Mutex or a channel?" say to use whichever is most expressive and/or most simple.
    There is an example of channel used for Mutex, but as commented:

    While channels provides a nice solution to protected data, it is a less efficient solution in the case of one writer and many readers.

    This threads adds:

    If you're sharing data, and never block in the locked section, just use a mutex.
    Mutexes are really cheap in the non-blocking case.

    If you have some shared service that does something complicated or long, and it has to be serialized, consider giving it its own goroutine that takes requests from a channel and sends replies back when done. Usually you send a struct with the input parameters and a channel object to be used for the reply.
    This works a lot like RPC.

    Channels are for communication, not locking.
    If you're sending meaningless data over a channel for locking purposes only, you're probably overcomplicating things.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度