Pan*_*lde 4 go goroutine go-iris
我想在超时时停止执行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
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
Timed out
test
test1
Run Code Online (Sandbox Code Playgroud)
预期产出:
Timed out
Run Code Online (Sandbox Code Playgroud)
有人能指出这里缺少什么吗?它确实超时但仍然运行goroutine打印test和test1.我只想在超时后立即停止执行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")
}
Run Code Online (Sandbox Code Playgroud)
没有好的方法可以在执行过程中"中断"执行goroutine.
Go使用并发的fork-join模型,这意味着你"fork"创建一个新的goroutine,然后在你到达"join point"之前无法控制goroutine的调度方式.连接点是多个goroutine之间的某种同步.例如,在频道上发送值.
以您的具体为例,这一行:
ch <- Response{data: "data", status: true}
Run Code Online (Sandbox Code Playgroud)
...无论如何都能发送值,因为它是一个缓冲通道.但是你创建的超时时间是:
case <-time.After(50 * time.Millisecond):
return "Timed out", false
Run Code Online (Sandbox Code Playgroud)
这些超时位于频道的"接收者"或"读者",而不是 "发送者".如本答案顶部所述,没有使用某些同步技术就无法中断goroutine的执行.
因为超时是从频道"读取"的,所以没有什么可以阻止在频道上发送的goroutine的执行.