doumu5934 2014-01-08 10:37
浏览 187
已采纳

Goroutine在多核处理器上的表现如何

I am a newbie in Go language, so please excuse me if my question is very basic. I have written a very simple code:

func main(){
    var count int // Default 0

    cptr := &count

    go incr(cptr)

    time.Sleep(100)

    fmt.Println(*cptr)
}

// Increments the value of count through pointer var
func incr(cptr *int) {
    for i := 0; i < 1000; i++ {
            go func() {
                    fmt.Println(*cptr)
                    *cptr = *cptr + 1
            }()
      }
    }

The value of count should increment by one the number of times the loop runs. Consider the cases:

Loop runs for 100 times--> value of count is 100 (Which is correct as the loop runs 100 times).

Loop runs for >510 times --> Value of count is either 508 OR 510. This happens even if it is 100000.

I am running this on an 8 core processor machine.

  • 写回答

4条回答 默认 最新

  • dthswrp84966 2014-01-08 11:31
    关注

    First of all: prior to Go 1.5 it runs on a single processor, only using multiple threads for blocking system calls. Unless you tell the runtime to use more processors by using GOMAXPROCS.

    As of Go 1.5 GOMAXPROCS is set to the number of CPUS. See 6, 7 .

    Also, the operation *cptr = *cptr + 1 is not guaranteed to be atomic. If you look carefully, it can be split up into 3 operations: fetch old value by dereferencing pointer, increment value, save value into pointer address.

    The fact that you're getting 508/510 is due to some magic in the runtime and not defined to stay that way. More information on the behaviour of operations with concurrency can be found in the Go memory model.
    You're probably getting the correct values for <510 started goroutines because any number below these are not (yet) getting interrupted.

    Generally, what you're trying to do is neither recommendable in any language, nor the "Go" way to do concurrency. A very good example of using channels to synchronize is this code walk: Share Memory By Communicating (rather than communicating by sharing memory)

    Here is a little example to show you what I mean: use a channel with a buffer of 1 to store the current number, fetch it from the channel when you need it, change it at will, then put it back for others to use.

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

报告相同问题?

悬赏问题

  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler
  • ¥15 关于#python#的问题:自动化测试