Go lang中线程的同步

时间:2015-01-23 00:46:42

标签: multithreading go

我想更多地了解线程的同步如何工作。在这里,我的程序功能正常,它使用完成通道进行同步。

package main

import (
    . "fmt"
    "runtime"
)

func Goroutine1(i_chan chan int, done chan bool) {
    for x := 0; x < 1000000; x++ {
        i := <-i_chan
        i++
        i_chan <- i
    }
    done <- true
}
func Goroutine2(i_chan chan int, done chan bool) {
    for x := 0; x < 1000000; x++ {
        i := <-i_chan
        i--
        i_chan <- i
    }
    done <- true
}

func main() {
    i_chan := make(chan int, 1)
    done := make(chan bool, 2)
    i_chan <- 0

    runtime.GOMAXPROCS(runtime.NumCPU())
    go Goroutine1(i_chan, done)
    go Goroutine2(i_chan)
    <-done
    <-done
    Printf("This is the value of i:%d\n", <-i_chan)
}

然而,当我尝试在没有任何同步的情况下运行它时。使用等待语句而没有通道来指定它何时完成,因此没有同步。

const MAX = 1000000

func Goroutine1(i_chan chan int) {
    for x := 0; x < MAX-23; x++ {
        i := <-i_chan
        i++
        i_chan <- i
    }
}

func main() {
    i_chan := make(chan int, 1)
    i_chan <- 0
    runtime.GOMAXPROCS(runtime.NumCPU())
    go Goroutine1(i_chan)
    go Goroutine2(i_chan)
    time.Sleep(100 * time.Millisecond)
    Printf("This is the value of i:%d\n", <-i_chan)
}

它打印出错误的i值。如果你延迟等待1秒,那么它将完成并打印出正确的声明。我有点明白,在你打印i_chan上的内容之前,两个帖子都没有完成,我只是对它的运作方式有点好奇。

1 个答案:

答案 0 :(得分:1)

请注意您的first example would deadlock, since it never calls GoRoutine2(OP自编辑问题以来) 如果是it calls GoRoutine2, then the expected i value is indeed 0

如果没有同步,(作为in this example),则无法保证main()在完成Goroutine1()和{{1}之前不会退出 }}。
对于1000000循环,1毫秒的等待似乎已经足够了,但同样,不能保证。

Goroutine2()

在&#34; How to Wait for All Goroutines to Finish Executing Before Continuing&#34;上查看更多内容,其中规范的方式是使用sync package’s WaitGroup structure,如this runnable example