[英]golang read and write from same channel
問題代碼是:
go func() {
defer wg.Done()
for {
task := <-tasks
if task.Attemts >= .5 {
tasks <- task # <- error
}
Println(task)
}
}()
在另一個循環中填充tasks <- Task{"1", rand.Float64()}
。
現在我們陷入了僵局……
完整示例: https : //play.golang.org/p/s1pnb1Mu_Y
我的代碼的重點是 - 創建 web scraper ,它會在失敗后嘗試解析 url。 進行一些嘗試,然后刪除 url。
可能在 golang 中,我們有一些更理想化的方法來解決這個問題,因為我不知道。
您使用的是非緩沖通道,因此當您嘗試使用tasks <- task
發送tasks <- task
該 goroutine 中的tasks <- task
執行坐在那里等待其他內容在通道上讀取。 由於頻道上沒有其他內容正在閱讀,因此您會陷入僵局。
使此特定代碼工作的唯一方法是擁有一個完全專用的使用者或使用緩沖通道。 即使這里有一個緩沖通道,如果緩沖區在您的單個消費者嘗試發送時填滿,您也可能會陷入死鎖。
如果你真的需要從同一個 goroutine 發送,你將不得不生成一個新的 goroutine 來發送它。 類似的東西
go func() {
tasks <- task
}()
或者你可以有這樣的事情:
requeue = make(chan Task) // could buffer if you want
go func() {
for {
tasks <- requeue
}
}()
for {
task := <-tasks
if task.Attemts >= .5 {
requeue <- task
}
Println(task)
}
當然,處理該通道的關閉等。
如果這是從通道讀取的唯一 goroutine,則它也不能寫入。
如果您使用緩沖通道,它可能會有點工作,但這只會將您的問題推回去。 你真正想做的可能是使用
go func(){
tasks <- task
}()
而不是簡單的tasks <- task
。 這會將寫入卸載到另一個 goroutine,因此這個 goroutine 可以直接返回讀取。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.