在等待wg.Wait()之后,使用带有waitgroup的多个go例程将数据写入同一通道时,出现异常,表明所有go例程处于睡眠状态或解除锁定。
package main
import (
"fmt"
"runtime"
"sync"
)
var wg sync.WaitGroup
func CreateMultipleRoutines() {
ch := make(chan int)
for i := 0; i < 10; i++ { // creates 10 go routines and adds to waitgroup
wg.Add(1)
go func() {
for j := 0; j < 10; j++ {
ch <- j
}
wg.Done() // indication of go routine is done to main routine
}()
}
fmt.Println(runtime.NumGoroutine())
wg.Wait() //wait for all go routines to complete
close(ch) // closing channel after completion of wait fo go routines
for v := range ch { // range can be used since channel is closed
fmt.Println(v)
}
fmt.Println("About to exit program ...")
}
当试图在没有等待组的情况下实现此操作时,我可以通过循环将数据推送到通道的确切次数来从通道读取数据,但是我无法调整范围,因为当我们关闭通道时会出现恐慌。这是示例代码
package main
import (
"fmt"
"runtime"
)
func main() {
ch := make(chan int)
for i := 0; i < 10; i++ { // creates 10 go routines and adds to waitgroup
go func(i int) {
for j := 0; j < 10; j++ {
ch <- j * i
}
}(i)
}
fmt.Println(runtime.NumGoroutine())
for v := 0; v < 100; v++ {
fmt.Println(<-ch)
}
fmt.Println("About to exit program ...")
}
我想了解为什么即使所有go例程都发出Done()信号,处于等待状态的waitgroup为何仍在等待,这反过来使go例程的数量为零
答案 0 :(得分:2)
我认为您的原始代码存在一些问题。
我的解决方案是产生一个新的goroutine来监视10个goroutine是否完成了工作。在那里,您将使用自己的<script type="text/javascript">
const el = document.getElementsByClassName('scrollable')[0]
const settouch = (e) => el.style.webkitOverflowScrolling = 'touch'
el.addEventListener("touchend", settouch, false);
</script>
。
然后代码如下:
WaitGroup
答案 1 :(得分:1)
默认情况下,chan
不保存任何项目,因此所有go例程在发送时都会被阻止,直到从中读取某些内容为止。他们实际上从未到达wg.Done()
语句。
一种解决方案是在自己的go例程中关闭通道。将您的wg.Wait()
和close(ch)
行换成这样:
go func() {
wg.Wait() //wait for all go routines to complete
close(ch) // closing channel after completion of wait fo go routines
}()
然后,您可以在通道上进行选择,该通道仅在所有发送go例程完成后(隐式接收到所有值)才会关闭。