Go 使用上下文取消子进程的执行
我试图弄清楚如何在Go中使用上下文模式。 我模拟的情况是,由于执行超时,需要取消多个长时间运行的子goroutine。据我所知,上下文的主要用途之一是在I/O超时或用户在处理结束前离开页面时停止所有子进程 我的代码:Go 使用上下文取消子进程的执行,go,Go,我试图弄清楚如何在Go中使用上下文模式。 我模拟的情况是,由于执行超时,需要取消多个长时间运行的子goroutine。据我所知,上下文的主要用途之一是在I/O超时或用户在处理结束前离开页面时停止所有子进程 我的代码: package main import ( "context" "fmt" "time" ) func doIt(ctx context.Context, filename string) { // simulate not ending fil
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
}
}
我希望在“文件处理超时”之后不会看到“处理文件”行
如何修复它
编辑:@Mellow旱獭指出,环境本身并不能阻止孩子们外出,为此提出了解决方案。但是他的更改是在doIt函数中的循环中进行的,这并不能完全回答这个问题,因为在doIt函数中没有for循环,而是可能存在无法更改的第三方(或stdlib)函数调用
所以让我重新表述一下问题-
如何取消一些长时间运行的进程,以
没有访问权限-挂起时间超过超时时间
上下文本身不会停止子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:
}
}
}
func doIt(ctx context.context,文件名字符串){
//模拟不结束文件处理
为了{
fmt.Printf(“正在处理文件%s\n”,文件名)
时间。睡眠(50*时间。毫秒)
挑选{
case上下文本身不会停止子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:
}
}
}
func doIt(ctx context.context,文件名字符串){
//模拟不结束文件处理
为了{
fmt.Printf(“正在处理文件%s\n”,文件名)
时间。睡眠(50*时间。毫秒)
挑选{
谢谢。但第一个循环周期在线锁定"案例但是如何取消一些长时间运行的进程,这些进程的内部我没有访问权——比如说,替代函数doIt的是一些第三方或stdlib函数——它们的挂起时间超过超时时间。@sev3ryn除非在goroutine中执行的代码提供了一种机制,否则无法取消长时间运行的goroutine。t这里没有机制可以杀死在goroutine中执行的代码外部的goroutine。谢谢。但是第一个循环循环会锁定行"案例但是如何取消一些长时间运行的进程,这些进程的内部我没有访问权——比如说,替代函数doIt的是一些第三方或stdlib函数——它们的挂起时间超过超时时间。@sev3ryn除非在goroutine中执行的代码提供了一种机制,否则无法取消长时间运行的goroutine。t在goroutine中执行的代码外部没有杀死goroutine的机制。