第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

關(guān)閉完成通道后,goroutine 缺少打印

關(guān)閉完成通道后,goroutine 缺少打印

Go
當(dāng)年話下 2023-08-14 17:00:02
當(dāng)我注意到并非管道中的所有關(guān)閉打印都被打印時,我根據(jù)《Go 中的并發(fā)》一書中的示例運行以下代碼??吹?amp;ldquo;完成倍增!&rdquo;?不見了。另一方面,NumGoroutine() 顯示僅主函數(shù)正在運行。下面的代碼有什么問題?package mainimport (? ? "fmt"? ? "runtime"? ? "time")func main() {? ? generator := func(done <-chan struct{}) <-chan int {? ? ? ? intStream := make(chan int)? ? ? ? i:=0? ? ? ? go func() {? ? ? ? ? ? defer close(intStream)? ? ? ? ? ? for {? ? ? ? ? ? ? ? select {? ? ? ? ? ? ? ? case <-done:? ? ? ? ? ? ? ? ? ? fmt.Println("done generator!")? ? ? ? ? ? ? ? ? ? return? ? ? ? ? ? ? ? case intStream <- i:? ? ? ? ? ? ? ? ? ? time.Sleep(1 * time.Second)? ? ? ? ? ? ? ? ? ? i++? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? fmt.Println("generator after select")? ? ? ? ? ? }? ? ? ? }()? ? ? ? return intStream? ? }? ? multiply := func(? ? ? ? done <-chan struct{},? ? ? ? intStream <-chan int,? ? ? ? multiplier int,? ? ) <-chan int {? ? ? ? multipliedStream := make(chan int)? ? ? ? go func() {? ? ? ? ? ? defer close(multipliedStream)? ? ? ? ? ? for i := range intStream {? ? ? ? ? ? ? ? select {? ? ? ? ? ? ? ? case <-done:? ? ? ? ? ? ? ? ? ? fmt.Println("done multiply !")? ? ? ? ? ? ? ? ? ? return? ? ? ? ? ? ? ? case multipliedStream <- i * multiplier:? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? fmt.Println("multiply after select")? ? ? ? ? ? }? ? ? ? }()? ? ? ? return multipliedStream? ? }? ? add := func(? ? ? ? done <-chan struct{},? ? ? ? intStream <-chan int,? ? ? ? additive int,? ? ) <-chan int {? ? ? ? addedStream := make(chan int)? ? ? ? go func() {? ? ? ? ? ? defer close(addedStream)? ? ? ? ? ? for i := range intStream {? ? ? ? ? ? ? ? select {? ? ? ? ? ? ? ? case <-done:? ? ? ? ? ? ? ? ? ? fmt.Println("done add !")? ? ? ? ? ? ? ? ? ? return? ? ? ? ? ? ? ? case addedStream <- i + additive:? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? fmt.Println("add after select")? ? ? ? ? ? }? ? ? ? }()? ? ? ? return addedStream? ? }
查看完整描述

2 回答

?
眼眸繁星

TA貢獻1873條經(jīng)驗 獲得超9個贊

有些代碼路徑不會打印某些消息done。調(diào)度程序碰巧選擇了一個不打印 的那個multiply。如果您稍微更改代碼(例如,在與現(xiàn)在不同的實例上登錄),您會發(fā)現(xiàn)它也可能會錯過該消息add?done。原因如下:

如果done消息在生成器將數(shù)字寫入通道并且乘法器讀取它之后立即到達,則乘法器會看到該數(shù)字done可用并選擇該數(shù)字。multiplier打印消息時就是這種情況done。如果當(dāng)donemultiplier 在 for 循環(huán)中等待時消息到達,則 multiplier 將接收輸入通道(而不是通道)上的關(guān)閉消息done,從而導(dǎo)致 for 循環(huán)終止而不打印done消息。

出現(xiàn)問題的原因是您正在 for 循環(huán)中讀取通道,然后進行選擇。在等待 for 循環(huán)從通道讀取數(shù)據(jù)時,不會評估與 select 相關(guān)的任何事件。

處理此問題的更好方法是不使用 for 循環(huán)從通道讀取。例如:

for {

? ? ?select {

? ? ? ? case <-done:

? ? ? ? ? ?return

? ? ? ? case i, ok:= <-intstream:

? ? ? ? ? ?if !ok {

? ? ? ? ? ? ? return

? ? ? ? ? ?}

? ? ? ? ? ?select {

? ? ? ? ? ? ? ?case <- done:

? ? ? ? ? ? ? ? ? ? return

? ? ? ? ? ? ? ?case addedStream <- i + additive:

? ? ? ? ? ?}

? ? ?}

}


查看完整回答
反對 回復(fù) 2023-08-14
?
一只甜甜圈

TA貢獻1836條經(jīng)驗 獲得超5個贊

你的add例程multiply不是永遠循環(huán),而是for ... range循環(huán)。因此,在每個循環(huán)的頂部,它們等待下一個整數(shù),而不是等待從其流select接收關(guān)閉done或?qū)⒔Y(jié)果發(fā)送到其流。這不是問題,但這意味著如果它們的輸入流關(guān)閉,它們將返回而不進入循環(huán)本身。

如果我添加fmt.Println調(diào)用來公開它們由于到達輸入流末尾而退出的點,則行為會略有變化(可能是由于時間原因;同時我正在輸入這個),輸出變成:

add after select

2

multiply after select

generator after select

multiply after select

add after select

4

generator after select

multiply after select

add after select

6

generator after select

Closed done

done multiply !

add got end of stream - done!

finished iterating pipeline

generator after select

done generator!

ramaining goroutines: 1

finished!

通常更合理的做法是僅讓生成器本身接收done信號,并讓管道函數(shù)始終寫入其所有結(jié)果,這使它們更可預(yù)測。當(dāng)然,無論誰正在讀取每個管道,都必須讀到最后——但是您已經(jīng)在主 goroutine 中執(zhí)行了此操作,因此我們只是將其傳播到整個管道。 這是您的代碼的簡化版本,以這種方式執(zhí)行此操作;它輸出:


2

generator after select

4

generator after select

6

generator after select

Closed done

8

generator after select

done generator!

multiply got end of stream - done!

add got end of stream - done!

finished iterating pipeline

remaining goroutines: 1

請注意,這一次,我們從最終生成值 (3) 中得到最終計算值 (8)。


查看完整回答
反對 回復(fù) 2023-08-14
  • 2 回答
  • 0 關(guān)注
  • 186 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號