首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
beego
V2EX  ›  Go

如何非侵入式的停止一个 goroutine

  •  
  •   lasuar · 52 天前 · 2099 次点击
    这是一个创建于 52 天前的主题,其中的信息可能已经有所发展或是发生改变。
    是的,我的意思有点类似 kill 它,而不是退出它。
    我正在为实现这样一个功能苦恼,标准库中的 context, sync.WaitGroup 都只是辅助开发者来关闭或等待一个 goroutine 关闭,而我想要实现一个:func executeFunc(myFunc, timeout)的方式,当 timeout 到达时,直接 kill 这个 goroutine,而不需要传任何与任务函数无关的参数来侵入 goroutine。
    在 Stack Overflow 上的答案是:没有这种方法,除非 Os.Exit to quit whole program.
    大家来发表一下意见啊~~~
    第 1 条附言  ·  52 天前
    更简单的阐述我的想法:
    线程记得吧,线程就有 kill/terminate 的方法来强行终止并回收资源。
    第 2 条附言  ·  52 天前
    此帖讨论结束
    21 回复  |  直到 2019-10-15 20:39:36 +08:00
        1
    xeaglex   52 天前 via Android
    Select 可以用来实现超时
        2
    reus   52 天前
    没有这种东西,你这种设计才是粗暴的侵入吧

    你可以用多个程序,然后用 exec.Cmd.Process.Kill
        3
    rrfeng   52 天前
    既然都设置 timeout 了那就用 context.Cancel() 呗。也加不了几行。
        4
    index90   52 天前
    标准的方式用 ctx 控制超时啊
        5
    yeya24   52 天前 via iPhone
    协程本身就不支持这样的,只能协程自己退出。你想结束它唯一办法就是 kill
        6
    lasuar   52 天前
    @reus 谢谢你提出的方法,不过这不是一种轻的实现方式没有满足我的想法。
    不过请问下我的方式侵入什么了?怎么个侵入法?
        7
    lasuar   52 天前
    @xeaglex
    @rrfeng
    谢谢回复,不过你们没有理解我的意思
        8
    lasuar   52 天前
    @yeya24 但是 golang 不支持 kill 哇,或者说我不知道为什么 go 官方不提供 kill 方法。
        9
    reus   52 天前
    @lasuar 侵入了 goroutine 的执行

    从外部是没法控制的,你可以想下怎样从内部控制,让函数里面不得不调用一些检查
        10
    index90   52 天前
    goroutine 不是线程啊,而 go 又没有 vm 给你做协程的控制,协程就是有用户(开发者)自己用代码控制的啊。
        11
    hst001   52 天前
    你这个想法太暴力了,最好是协程能自己控制,超时到的时候释放各种资源然后退出协程
        12
    lasuar   52 天前
    @index90 老哥点破我了,确实协程的概念是开发者调度的。好吧,也许是 golang 的 go func()这种极简的设计方式让我把对线程的思考方式代入协程里面了。
        13
    reus   52 天前   ♥ 1
    @lasuar https://tip.golang.org/doc/faq#no_goroutine_id

    因为官方认为 goroutine 不应该有 id,那自然就不会有从外部控制的方法
        14
    lasuar   52 天前
    @reus 3q,我先看看
        15
    reus   52 天前
    @lasuar goroutine 不是协程,开发者也没法控制调度。

    就算是操作系统线程,kill 系统调用也是发一个信号过去,退出不退出,线程本身也有一定选择权的,没有这么粗暴的
        16
    t123yh   52 天前 via Android
    一个线程并不是随时都可以安全退出的,在某些状态下,一个线程并不能安全地退出,如果这时它被强行结束,可能会破坏程序状态。所以需要你在线程中的“安全地带”处检测是否要退出线程并主动退出,而不能直接从外部 kill 掉它。
        17
    lasuar   52 天前
    @t123yh 了解,你说的是线程内使用了锁或者打开的文件资源这些情况吧。因为 kill 是 OS 提供的,调用是开发者执行的,所以开发者在 kill 的时候必须考虑到这些情况。这个就不在帖子讨论的主题范围了
        18
    xeaglex   52 天前 via Android   ♥ 1
    。。。楼主问个问题还这么有性格
        19
    rrfeng   52 天前   ♥ 2
    线程 /进程
    外部发送 kill 信号给它,它会在内部检测到,然后进行合适的处理,只是被封装好了你看不到这个而已 ---> 这个跟 context 解决 goroutine 是完全一致的。

    那么就只剩下 kill -9 的问题了:
    线程 /进程是有独立的资源的,强制终结之后操作系统会回收处理。不会影响其他程序运行。
    但是 goroutines 里有大量的共享资源,变量、内存、引用地址等等,根本无法辨别,所以就无法处理了。所以没有 kill -9
        20
    Leigg   52 天前 via Android
    @rrfeng 第一段话可以理解。 但是线程也可以使用全局变量,也可以做一些锁行为,这时候 kill 也会有问题,kill 与否由开发者决定。goroutine 拥有的资源线程一样有啊,你没有说到点子上。
        21
    useben   52 天前
    协程不是内核态的,不像进程和线程,分配了 pid,而且是应用层分配资源和调度的,所以没办法 kill
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   894 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 26ms · UTC 21:25 · PVG 05:25 · LAX 13:25 · JFK 16:25
    ♥ Do have faith in what you're doing.