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

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

如何修復(fù)2個(gè)通道互相死鎖

如何修復(fù)2個(gè)通道互相死鎖

Go
慕妹3146593 2023-08-14 15:14:40
我有這段Go代碼。我需要具備這種能力:在一個(gè)地方寫入通道,然后在另一個(gè)地方讀出它們(反之亦然):package mainimport "fmt"var ch1=make(chan int)var ch2=make(chan int)func f1() {    select {    case <- ch1:fmt.Println("ch1")    default: fmt.Println("default")    }}func f2() {    select {    case <- ch2:fmt.Println("ch2")    default: fmt.Println("default")    }}func main() {    go f1()    go f2()    ch1<-1    ch2<-2}它總是像這樣打?。篸efaultch1fatal error: all goroutines are asleep - deadlock!goroutine 1 [chan send]:main.main()    /tmp/sandbox970110849/prog.go:22 +0xa0此外我嘗試了這個(gè):package mainimport (    "fmt"    "sync")var ch1=make(chan int)var ch2=make(chan int)func f1() {    select {    case <- ch1:fmt.Println("ch1")    default: fmt.Println("default")    }}func f2() {    select {    case <- ch2:fmt.Println("ch2")    default: fmt.Println("default")    }}func w1() {    ch1 <-1}func w2() {    ch2 <-1}func main() {    var wg sync.WaitGroup    wg.Add(4)    go f1()    go f2()    go w1()    go w2()    wg.Wait()}這次錯(cuò)誤更多:defaultch2fatal error: all goroutines are asleep - deadlock!goroutine 1 [semacquire]:sync.runtime_Semacquire(0x40e028, 0x0)    /usr/local/go/src/runtime/sema.go:56 +0x40sync.(*WaitGroup).Wait(0x40e020, 0x14b720)    /usr/local/go/src/sync/waitgroup.go:130 +0x60main.main()    /tmp/sandbox916639182/prog.go:36 +0x100goroutine 8 [chan send]:main.w1()    /tmp/sandbox916639182/prog.go:23 +0x40created by main.main    /tmp/sandbox916639182/prog.go:34 +0xc0我哪里出了問題以及如何解決?
查看完整描述

2 回答

?
幕布斯7119047

TA貢獻(xiàn)1794條經(jīng)驗(yàn) 獲得超8個(gè)贊

您的main()函數(shù)嘗試在所有通道上發(fā)送,并且僅一次性嘗試在單獨(dú)的并發(fā) goroutine 中從這些通道中讀取數(shù)據(jù)。這是否成功取決于 goroutine 調(diào)度程序。如果非阻塞接收的安排f2()早于發(fā)送main(),那么后面的發(fā)送main()將永遠(yuǎn)阻塞(沒有人會再次嘗試接收ch2)。

擺脫死鎖的一種方法是使用接收操作而不是非阻塞接收(在Go Playground上嘗試一下):

func f1() {

? ? <-ch1

? ? fmt.Println("ch1")

}

func f2() {

? ? <-ch2

? ? fmt.Println("ch2")

}

因此,無論何時(shí)main()到達(dá)在這些通道上發(fā)送值的點(diǎn),總會有一個(gè)接收器準(zhǔn)備好繼續(xù),因此不會main()被卡住。

請注意,當(dāng)main()返回時(shí),應(yīng)用程序結(jié)束,它不會等待非主 goroutine 完成。因此您可能看不到ch1ch2打印在控制臺上。

如果您的目的是在您的應(yīng)用程序存在之前等待所有 goroutine 完成其工作,請使用sync.WaitGroup它(在Go Playground上嘗試):

var ch1 = make(chan int)

var ch2 = make(chan int)


var wg sync.WaitGroup


func f1() {

? ? defer wg.Done()

? ? <-ch1

? ? fmt.Println("ch1")

}


func f2() {

? ? defer wg.Done()

? ? <-ch2

? ? fmt.Println("ch2")

}


func main() {

? ? wg.Add(1)

? ? go f1()

? ? wg.Add(1)

? ? go f2()


? ? ch1 <- 1

? ? ch2 <- 2

? ? wg.Wait()

}


另一種選擇是為通道提供 1 的緩沖區(qū),這樣就可以在通道上發(fā)送 1 個(gè)值,而無需準(zhǔn)備好從通道接收的接收器(在Go Playgroundmain()上嘗試這個(gè)):

var?ch1?=?make(chan?int,?1)
var?ch2?=?make(chan?int,?1)

有了這個(gè),就可以在沒有和 的情況main()下繼續(xù),所以同樣,不能保證您會看到任何打印內(nèi)容。f1()f2()


查看完整回答
反對 回復(fù) 2023-08-14
?
慕少森

TA貢獻(xiàn)2019條經(jīng)驗(yàn) 獲得超9個(gè)贊

這里使用的通道是無緩沖通道。

  • 當(dāng)主協(xié)程啟動(dòng)時(shí),它會創(chuàng)建兩個(gè)新的協(xié)程 f1 和 f2。

  • 當(dāng)執(zhí)行 f1 或 f2 時(shí),它將檢查通道中是否有值,否則它將打印默認(rèn)消息并退出。

  • 在理想情況下,通道將首先發(fā)布值,然后通過 goroutine 接收它

  • 實(shí)際情況是 Goroutine 通過打印默認(rèn)情況退出,但主 Goroutine 試圖在通道中發(fā)布值,但由于沒有接收器,它面臨死鎖情況。

消除了第一個(gè)示例中的死鎖,請參閱鏈接:https ://play.golang.org/p/6RuQQwC9JkA

但是,如果主例程退出,所有關(guān)聯(lián)的 goroutine 將被自動(dòng)殺死。這就是為什么我們可以看到該值是任意打印的。

刪除了第二個(gè)示例中的死鎖,請參閱鏈接:https ://play.golang.org/p/yUmc_jjZMgV

sync.WaitGroup 正在使主 goroutine 等待,這就是為什么我們可以在每次程序執(zhí)行時(shí)觀察到輸出。


查看完整回答
反對 回復(fù) 2023-08-14
  • 2 回答
  • 0 關(guān)注
  • 179 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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