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

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

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

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

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

    因为官方认为 goroutine 不应该有 id,那自然就不会有从外部控制的方法
    lasuar
        14
    lasuar  
    OP
       2019-10-15 12:50:32 +08:00
    @reus 3q,我先看看
    reus
        15
    reus  
       2019-10-15 12:51:44 +08:00
    @lasuar goroutine 不是协程,开发者也没法控制调度。

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

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