首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  程序员

如何停止线程池中的线程

  •  
  •   rizon · 37 天前 · 1881 次点击
    这是一个创建于 37 天前的主题,其中的信息可能已经有所发展或是发生改变。

    本来以为是个很简单的事,用起来才发现完全不是那么回事。。。

    场景是这样的,我用线程池去运行一个任务,希望在任务超时后就可以停止掉。 可是我发现 get 的超时不会让线程停下来,cancle 也不会让线程停下来。。。

    所以到底该怎么停止线程?释放出线程池?

    第 1 条附言  ·  37 天前
    那再问一下,线程里面开线程。父线程退出后,子线程还会继续运行吗
    11 回复  |  直到 2019-11-01 07:29:27 +08:00
        1
    defphilip   37 天前
    正确的做法,是不要去停止线程,线程正常消亡才是正常的逻辑
    要做取消,可以在外部设置类似于 disable 一样的标志位,线程内函数判断这个标志
        2
    ClericPy   37 天前
    这个不管什么语言, 在 stackoverflow 上都有人很详细的分析了, 自己去看看吧, 基本是个费力不讨好的操作, 一般都是在线程内自己主动停下.

    目前就我所知, 除非语言本身考虑到处理这种情况, 不烦很复杂的. 比如在用 python 协程的时候, 挺多情况超时捎带的 cancel 可以把没跑完的协程给终止, 不过有些协程粒度不细, 还是停不下来.
        3
    yyyyfan   37 天前
    while(continueProcessing){
    ...
    }
    一般是采用标志位去停止,话说一般超时是会有回调的吧
        4
    DsuineGP   37 天前
    如果是 java 的话,调用执行线程的中断(interrupt)方法,在执行线程的业务代码中可以响应中断,并处理一些释放资源的逻辑.
    但也并不是所有的线程状态都能响应中断,并发库中有一些更容易使用更安全的类,推荐看一下.
        5
    rizon   37 天前 via iPhone
    @defphilip
    @ClericPy
    那再问一下,线程里面开线程。父线程退出后,子线程还会继续运行吗
        6
    ClericPy   37 天前
    对 py 来说, 取决于子线程是不是 daemon, talk is cheap

    from threading import Thread
    import time


    def parent():
    t = Thread(target=child)
    t.daemon = True
    t.start()
    for i in range(5):
    print('parent', i)
    time.sleep(0.5)


    def child():
    for i in range(10):
    print('child', i)
    time.sleep(0.5)


    t = Thread(target=parent)
    t.run()


    执行会发现父线程在子线程 daemon 是 True 的时候不等, False 或默认的时候等. (这是为了定义清晰, 实际主线程看做父线程也一个意思)

    但是注意, 这里的不等是不阻塞的意思, 结尾如果加一个 time.sleep(5), 会发现子线程是没有停止退出的, 这里不等只是让程序进程退出而不等.
        7
    ddup   37 天前 via Android
    子线程不会因为父线程的退出而停止,可以参考下 .NET CancellationToken 机制的实践。
        8
    yidinghe   37 天前 via Android
    线程实际上是没有……等下楼主你用的什么语言?
        9
    qyvlik   37 天前
    所有语言的线程实现都是类似的,包装了一次系统的线程。如果想停止正在运行中的线程,有几种方式:
    1. 代码中检查线程的状态,例如 Java 的 Thread.currentThread().isInterrupted()
    2. 语言本身支持 cpu 直接中断线程,然后把线程干掉,不过会有资源泄露的问题,毕竟不是正常退出。
    3. 脚本语言的实现支持线程中断,例如你可以自己实现一个脚本引擎,在做指令派发的时候,将 指令 与 线程状态做位运算,线程状态是 0 的话,得到的指令是 0,0 可以定义为中止执行,就达到线程中断的要求。可以看看具体的代码: https://github.com/qyvlik/tinyvm/blob/40bfefac61d9e0409572b5b0c97f700f6f1532c8/tinyvm.cpp#L83
    4. 进程被杀,线程一般也会退出,所以杀进程吧。
        10
    zhuangzhuang1988   37 天前
    @ddup 正解,微软的东西一直做得很完善的
    还有进度报告
        11
    simuhunluo   36 天前 via Android
    父进程被杀,子进程还在,并且他的父进程 ID 置为 1。可以设置子进程为守护进程,这样父进程杀了之后子进程也没了。
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   927 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 25ms · UTC 20:09 · PVG 04:09 · LAX 12:09 · JFK 15:09
    ♥ Do have faith in what you're doing.