首页 > 解决方案 > Golang线程不是每次都执行

问题描述

所以,我正在测试 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 行。我哪里错了?

标签: multithreadinggo

解决方案


当您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. 此外,您不得sync.Mutex在第一次使用后复制 a,如文档中所述。这不会发生在您的情况下,因为您在使用 之前复制sync.Mutex,但请注意它。


推荐阅读