Golang线程不是每次都执行

时间:2018-10-09 09:46:19

标签: multithreading go

所以,我正在测试Golang。我了解fmt.Println不是线程安全的。因此,我正在尝试sync.Mutex。以下是程序:

func threder(mux *Mutex, i int) {
    mux.Lock()
    fmt.Println("I am thread: ", i)
    mux.Unlock()
    return
}

func main() {
    m := &Mutex{}
    for i := 0; i < 300; i++ {
        go threder(m, i)
    }
}

我希望输出300行。但是,我得到80-90行。我在哪里错了?

1 个答案:

答案 0 :(得分:4)

当您的main返回时,所有其他线程都被杀死。由于main在启动所有线程后立即返回,因此其中一些无法打印。您可以使用sync.WaitGroup等待所有线程停止:

func main() {
    m := &sync.Mutex{}
    var wg sync.WaitGroup
    for i := 0; i < 300; i++ {
        wg.Add(1)
        go func(i int) {
            defer wg.Done()
            threder(m, i)
        }(i)
    }
    wg.Wait()
}

关于您的注释:如果您不传递sync.Mutex作为指针,而是将值传递给函数sync.Mutex,则该副本将被复制,并且每个副本将彼此独立地操作。因此,线程之间将不会同步,因为它们都使用自己的独立sync.Mutex。另外,如docs所述,首次使用后不得复制sync.Mutex。对于您而言,这不会发生,因为您在使用sync.Mutex之前进行了复制,但是请注意这一点。