2 回答
TA贡献1863条经验 获得超2个赞
如果通道中没有空间,则在通道上发送也会阻止。如果在通道中使用缓冲区,则发送可以工作。仅使用 1:
ch := make(chan bool, 1)
现在,您可以发送数据,并且它不会阻止go例程,因为它没有满。如果您在没有读取的情况下再次发送,那么它将阻止发送调用,因为再次没有空间并且仍然没有消耗以前的值。
关于打印的顺序:没有顺序,其中go例程将首先开始,go lang规范没有提到多个go例程是否从一个通道接收数据,那么首先等待的人是否真的首先获得它。因此,如果需要,您需要添加其他同步以维护顺序。以下是订购同步的提示。
下面是打印的修改代码,但我更喜欢不同的方法。检查上面链接中的乒乓球示例,其中使用了2个单独的通道而不是一个。
package main
import (
"fmt"
"sync"
)
func odd(wg *sync.WaitGroup, ch chan bool) {
defer wg.Done()
i := 1
for i <= 10 {
<-ch
fmt.Println(i)
i += 2
ch <- true
}
}
func even(wg *sync.WaitGroup, ch chan bool) {
defer wg.Done()
i := 2
for i <= 10 {
<-ch
fmt.Println(i)
i += 2
ch <- true
}
}
func main() {
var wg sync.WaitGroup
ch := make(chan bool, 1)
defer close(ch)
wg.Add(2)
go even(&wg, ch)
go odd(&wg, ch)
ch <- true
wg.Wait()
}
TA贡献2080条经验 获得超4个赞
首先,您的两个 Goroutine 需要从通道接收才能开始工作ch
for i<=10{
<-ch // wait until receive
fmt.Println(i)
i+=2
ch <- true
}
因此,您将值发送到通道,以使两个 goroutine 工作ch
func main() {
//...
ch <- true
//...
}
但这不会像预期的那样工作,因为你们的两个goroutine共享同一个频道。执行时,只有一个可以接收、开始工作并将值发送回通道。chch <- truemain()ch
之后,两个 goroutine 不断从通道接收,开始工作并将值发送回通道ch
换句话说,两个 goroutine 通过使用通道相互发送和接收值ch
for i<=10 {
<-ch // receive when main() executed at first time, after that receive from another goroutine
fmt.Println(i) // start work
i+=2 //
ch <- true // return back to the channel, another goroutine will receive it
}
wg.Done()
但问题是,当一个goroutine退出时,剩余的goroutine仍然试图在下班后发送到通道,但没有接收器,这会导致死锁ch
- 2 回答
- 0 关注
- 107 浏览
添加回答
举报