gpt4 book ai didi

go - 使用上下文取消子进程的执行

转载 作者:IT王子 更新时间:2023-10-29 01:58:35 25 4
gpt4 key购买 nike

我正在尝试弄清楚如何在 Go 中使用上下文模式。我正在模拟多个长时间运行的子 goroutines 由于执行超时而需要取消的情况。据我了解,上下文的主要用途之一是在 I/O 超时或用户在处理结束前离开页面时停止所有子进程。

我的代码:

package main

import (
"context"
"fmt"
"time"
)

func doIt(ctx context.Context, filename string) {
// simulate not ending file processing -
// internals of this loop could not change
// e.g. it is call of some third party or stdlib function that hangs
for {
fmt.Printf("processing file %s\n", filename)
time.Sleep(50 * time.Millisecond)
}
}

func main() {
startFileProcessing()
fmt.Println("End of processing")
time.Sleep(500 * time.Millisecond)
fmt.Println("Do something else")

}

func startFileProcessing() {
// set file processing timeout
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*100)
defer cancel()

// start two parallel processes
go doIt(ctx, "file1")
go doIt(ctx, "file2")

select {
case <-ctx.Done():
fmt.Println("file processing timeout")
return
}
}

Playground .

哪些输出:

processing file file2
processing file file1
processing file file1
processing file file2
processing file file1
file processing timeout
End of processing
processing file file2
processing file file2
processing file file1
processing file file1
processing file file2
Do something else

我希望在“文件处理超时”后看不到“处理文件”行。

如何解决?

编辑:@Mellow Marmot 指出上下文不会自行停止子 goroutine,并为此提出了解决方案。但是他的更改是在 doIt 函数中的循环内,这并不能完全回答问题,因为在 doIt 函数中不是 for 循环,可能有一些第三方(或 stdlib)函数调用无法更改。

所以让我改一下问题 -

How to cancel some long running processes to internals of which I don't have access - that hangs for more time than timeout?

最佳答案

上下文不会自行停止子 goroutine。在 goroutine 中运行的应用程序代码必须检查上下文并在上下文完成时从 goroutine 返回。以下是如何检查上下文的示例:

func doIt(ctx context.Context, filename string) {
// simulate not ending file processing
for {
fmt.Printf("processing file %s\n", filename)
time.Sleep(50 * time.Millisecond)
select {
case <-ctx.Done():
return
default:
}
}
}

playground example

不可能取消长时间运行的 goroutine,除非 goroutine 中执行的代码提供了这样做的机制。没有用于在 goroutine 中执行的代码外部终止 goroutine 的机制。

关于go - 使用上下文取消子进程的执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39195703/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com