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 關注
- 137 瀏覽
添加回答
舉報