所以,我正在测试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行。我在哪里错了?
答案 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
之前进行了复制,但是请注意这一点。