使用os杀死python线程

时间:2015-02-20 16:11:15

标签: python linux multithreading

我已经多次问过类似的问题,但仍然找不到合适的解决方案。

我有外部功能,在某些情况下可以运行很长时间。我想在30秒之后打断它。

我该怎么做?

  1. 线程很好,但是我不能使用它们(我无法访问外部函数的代码)
  2. 多处理也不是一种选择,因为我在mod_wsgi下运行网站。
  3. 有没有可靠的方法来阻止线程? 也许使用os.system或os.kill。如果是,那怎么办?

    外部功能仅执行一些caclulations,没有网络连接或文件打开。所以,我只需要停止处理并清理。

    我的代码(实际上是从某些来源获取的):

    def time_limit(timeout):
        def internal(function):
            def internal2(*args, **kw):
                class MyThread(threading.Thread):
                    def __init__(self):
                        threading.Thread.__init__(self)
                        self.result = None
                        self.error = None
    
                    def run(self):
                        try:
                            self.result = function(*args, **kw) # this is external
                        except Exception as e:
                            self.error = e
    
                    def _stop(self):
                        if self.isAlive():
                            threading.Thread._Thread__stop(self)
    
                c = MyThread()
                c.start()
                c.join(timeout)
                counter = 0
                if c.isAlive():
                    c._stop()
                    raise TimeoutException
                if c.error:
                    raise c.error
                return c.result
            return internal2
        return internal
    

4 个答案:

答案 0 :(得分:1)

你无法杀死线程,但你可以杀死一个进程。如果您可以使用进程代替线程,则可以使用multithreading module。来自父应用程序的进程可以是terminated

如果您更详细地描述您的任务,也许我可以提供更多帮助。

答案 1 :(得分:0)

不,没有办法从外部停止线程。线程完全控制产生它的过程,从外部杀死它意味着你必须弄乱进程内存,这通常意味着你使进程失效;你通常做的是以某种形式处理消息,允许线程自己以某种外部冲动终止。

答案 2 :(得分:0)

它可能不是终止线程的最佳方式,但this answer提供了一种杀死线程的方法。请注意,您可能还需要实现一种方法,让线程在其代码的关键部分中不可攻击。


为方便起见,下面包含代码和用法示例:

import threading
import sys

class StopThread(StopIteration): pass

threading.SystemExit = SystemExit, StopThread

class Thread2(threading.Thread):

    def stop(self):
        self.__stop = True

    def _bootstrap(self):
        if threading._trace_hook is not None:
            raise ValueError('Cannot run thread with tracing!')
        self.__stop = False
        sys.settrace(self.__trace)
        super()._bootstrap()

    def __trace(self, frame, event, arg):
        if self.__stop:
            raise StopThread()
        return self.__trace


class Thread3(threading.Thread):

    def _bootstrap(self, stop_thread=False):
        def stop():
            nonlocal stop_thread
            stop_thread = True
        self.stop = stop

        def tracer(*_):
            if stop_thread:
                raise StopThread()
            return tracer
        sys.settrace(tracer)
        super()._bootstrap()

################################################################################

import time

def main():
    test = Thread2(target=printer)
    test.start()
    time.sleep(1)
    test.stop()
    test.join()

def printer():
    while True:
        print(time.time() % 1)
        time.sleep(0.1)

if __name__ == '__main__':
    main()

Thread3类似乎运行代码的速度比Thread2类快大约33%。

答案 3 :(得分:0)

您可以使用os.system执行终端命令,这样您就可以在程序中进行终端控制。如果你想

import os
os.system("terminal command goes here")

for linux阅读: https://www.digitalocean.com/community/tutorials/how-to-use-ps-kill-and-nice-to-manage-processes-in-linux

了解pthread_kill() Stack exchange - how to kill a thtread

对于Windows,

http://forum.thewindowsclub.com/windows-tips-tutorials-articles/29463-kill-processes-using-command-prompt-windows-7-8-a.html

对于mac: http://www.chriswrites.com/how-to-view-and-kill-processes-using-the-terminal-in-mac-os-x/

可替换地:

import signal
signum = signal.getsignal(c)
signal.siginterrupt(signum, flag)

OR:

import os
sigID = c.get_ident 
os.system("kill -SIGKILL " + sigID)

signal doc page 还可以设置一些定时器功能。

有关python线程的其他信息: https://docs.python.org/2/library/thread.html