超时时停止goroutine执行
我想在超时时停止goroutine执行。但它似乎对我不起作用。我正在使用超时时停止goroutine执行,go,goroutine,go-iris,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)
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
有人能指出这里缺少什么吗?它确实超时,但仍然运行goroutine来打印test
和test1
。我只想在超时时停止执行GOODUTIN。< P> >在执行过程中没有中断GORUTIN执行的好方法。
Go使用并发的fork-join模型,这意味着您“fork”创建一个新的goroutine,然后在到达“连接点”之前无法控制该goroutine的调度方式。连接点是多个goroutine之间的某种同步。e、 g.在通道上发送值
以您的具体示例为例,这一行:
ch <- Response{data: "data", status: true}
ch控制您的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")
}
ctx,cancel:=context.WithCancel(context.Background())
推迟取消
ch:=制造(chan响应,1)
go func(){
时间。睡眠(1*时间。秒)
挑选{
违约:
ch您有一个goroutine泄漏,您必须在超时之前处理一些已完成的操作以返回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
}
}
func(s*CicService)Find()(接口{},bool){
ch:=制造(chan响应,1)
完成:=make(chan结构{})
go func(){
挑选{
案例此示例不起作用。即使您将超时设置为case,您也永远无法读取ch
。谢谢@MikeKlemin,用正确的行为更新了我的答案。此外,虽然睡眠只是“工作到此为止”的一个示例,但如果您确实需要睡眠(例如在轮询周期之间等待),创建一个时间通道是一个好主意,例如,此示例仅对Time.Sleep
tho有用。如果有一个长时间运行的函数,它不能中断它(没有提前终止)…此示例中没有打印。请使用得票最高的答案。警告:在检查ctx.Done()之前,这不会停止go例程
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")
}
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
}
}