其实我之前理解说waitgroup的add和done无法同步,当时就觉得很奇怪
for(i = 1;i <3 ;i++)
{
add(3)
go func(){
done
}()
wait
}
看过源码的都知道,done其实就是add,那么如果说我协程运行的很快,比方说我现在第一个协程都运行完了,然后
我去做这个wait,那这算不算同步呢??
再比方说吧
for(3)
{
go func()
{
add(1)
done
}
}
wait
其实这种包装的wait用法还是比较常见的,那么这么用会不会出问题呢???
答案是会,如果wait在add之前拿他肯定直接ok。
那如果wait在第一个add后,最后一个done前呢,其实这时候就不会出问题。
因为此时这个wait只是等待这一个done罢了。
waitgroup能够让已经done的wait也没关系。
但是如果全部done已经做到只剩最后一个,然后你中间把之前所有的wait都加进去更改了变量,这个其实是可以的。
但你不能在最后一个done执行的时候在这中间又把所有wait做完,这个就不行了。
就是说不能add到一半再wait做完再去add,这样就会很尴尬。。。
但由于done其实就是变相的add。
if w != 0 && delta > 0 && v == int32(delta) {
panic("sync: WaitGroup misuse: Add called concurrently with Wait")
if *statep != state {
panic("sync: WaitGroup misuse: Add called concurrently with Wait")
}
检测其实没有很严谨。
简单来讲就是第一个add必须在wait之前。
//add还没成功呢你就要wait
然后最后一个done也不能被wait中断,还是很严谨的。
//明明大家都已经做完了,你却wait等待
这个语言的细微之处还是很微妙的。