3 回答

TA貢獻(xiàn)1869條經(jīng)驗(yàn) 獲得超4個(gè)贊
您可以輕松驗(yàn)證
func helper(c chan<- error) {
time.Sleep(5 * time.Second)
c <- errors.New("") // send errors/nil on c
}
func worker() error {
fmt.Println("do one")
c := make(chan error, 1)
go helper(c)
err := <-c
fmt.Println("do two")
return err
}
func main() {
worker()
}
問(wèn):語(yǔ)句 err := <- c 阻塞工作者嗎?我不這么認(rèn)為,因?yàn)橥ǖ朗蔷彌_的。
- 答: err := <- c
會(huì)阻止工人。
問(wèn):如果是阻塞的,我如何使它成為非阻塞的?我的要求是讓 worker 及其調(diào)用者繼續(xù)完成其余的工作,而無(wú)需等待值出現(xiàn)在通道上。
A:如果您不想阻止,只需刪除err := <-c
. 如果你在最后需要錯(cuò)誤,只需移動(dòng)err := <-c
到最后。
沒有阻塞就無(wú)法讀取通道,如果沒有阻塞就不能再執(zhí)行此代碼,除非您的代碼處于循環(huán)中。
Loop:
for {
select {
case <-c:
break Loop
default:
//default will go through without blocking
}
// do something
}
你見過(guò)errgroup或 waitgroup 嗎?
它使用原子、取消上下文和sync.Once 來(lái)實(shí)現(xiàn)這一點(diǎn)。
https://github.com/golang/sync/blob/master/errgroup/errgroup.go
https://github.com/golang/go/blob/master/src/sync/waitgroup.go
或者你可以直接使用它,運(yùn)行你的函數(shù),然后在你想要的任何地方等待錯(cuò)誤。

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超7個(gè)贊
在您的代碼中,其余工作與幫助程序是否遇到錯(cuò)誤無(wú)關(guān)。其余工作完成后,您可以簡(jiǎn)單地從頻道接收。
func worker() error {
//do some work
c := make(chan error, 1)
go helper(c)
//do rest of the work
return <-c
}

TA貢獻(xiàn)1789條經(jīng)驗(yàn) 獲得超8個(gè)贊
我想你需要這個(gè)代碼..
運(yùn)行此代碼
package main
import (
"log"
"sync"
)
func helper(c chan<- error) {
for {
var err error = nil
// do job
if err != nil {
c <- err // send errors/nil on c
break
}
}
}
func worker(c chan error) error {
log.Println("first log")
go func() {
helper(c)
}()
count := 1
Loop:
for {
select {
case err := <- c :
return err
default:
log.Println(count, " log")
count++
isFinished := false
// do your job
if isFinished {
break Loop // remove this when you test
}
}
}
return nil
}
func main() {
wg := sync.WaitGroup{}
wg.Add(1)
go func() {
c := make(chan error, 1)
worker(c)
wg.Done()
}()
wg.Wait()
}
- 3 回答
- 0 關(guān)注
- 157 瀏覽
添加回答
舉報(bào)