[英]Stop goroutine execution on timeout
我想在超時時停止執行goroutine。 但似乎對我不起作用。 我正在使用iris
框架。
type Response struct {
data interface{}
status bool
}
func (s *CicService) Find() (interface{}, bool) {
ch := make(chan Response, 1)
go func() {
time.Sleep(10 * time.Second)
fmt.Println("test")
fmt.Println("test1")
ch <- Response{data: "data", status: true}
}()
select {
case <-ch:
fmt.Println("Read from ch")
res := <-ch
return res.data, res.status
case <-time.After(50 * time.Millisecond):
return "Timed out", false
}
}
輸出:
Timed out
test
test1
預期產量:
Timed out
有人可以指出這里缺少什么嗎? 它確實超時,但仍運行goroutine來打印test
和test1
。 我只想在超時后立即停止執行goroutine。
沒有好的方法可以在執行過程中“中斷” goroutine的執行。
Go使用並發的fork-join模型,這意味着您將“ fork”創建一個新的goroutine,然后無法控制該goroutine的調度方式,直到到達“ join point”為止。 連接點是多個goroutine之間的某種同步。 例如在通道上發送值。
以您的特定示例為例,此行:
ch <- Response{data: "data", status: true}
……無論如何,都將能夠發送該值,因為它是一個緩沖通道。 但是超時是您創建的:
case <-time.After(50 * time.Millisecond):
return "Timed out", false
這些超時在通道的“接收者”或“閱讀器”上, 而不在“發送者”上。 如該答案頂部所述,如果不使用某些同步技術,就無法中斷goroutine的執行。
由於超時是在goroutine從通道“讀取”中進行的,因此沒有什么可以停止在通道上發送的goroutine的執行。
控制goroutine處理的最佳方法是上下文 (std go庫)。
您可以取消goroutine中的某些內容並停止執行, 而不會發生goroutine泄漏 。
這是您的情況下通過超時取消的簡單示例 。
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ch := make(chan Response, 1)
go func() {
time.Sleep(1 * time.Second)
select {
default:
ch <- Response{data: "data", status: true}
case <-ctx.Done():
fmt.Println("Canceled by timeout")
return
}
}()
select {
case <-ch:
fmt.Println("Read from ch")
case <-time.After(500 * time.Millisecond):
fmt.Println("Timed out")
}
您有一個gouroutine泄漏,必須執行一些已完成的操作以在超時之前返回goroutine,如下所示:
func (s *CicService) Find() (interface{}, bool) {
ch := make(chan Response, 1)
done := make(chan struct{})
go func() {
select {
case <-time.After(10 * time.Second):
case <-done:
return
}
fmt.Println("test")
fmt.Println("test1")
ch <- Response{data: "data", status: true}
}()
select {
case res := <-ch:
return res.data, res.status
case <-time.After(50 * time.Millisecond):
done <- struct{}{}
return "Timed out", false
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.