是否有可能从python中的子线程中杀死父线程?

DJM*_*hem 6 python time multithreading

我在Windows上使用Python 3.5.2.

我想运行一个python脚本,但保证它不会超过N秒.如果确实需要超过N秒,则应引发异常,程序应退出.最初我以为我可以在开始时启动一个线程,在抛出异常之前等待N秒,但这只会设置为向计时器线程抛出异常,而不是父线程.例如:

import threading
import time

def may_take_a_long_time(name, wait_time):
    print("{} started...".format(name))
    time.sleep(wait_time)
    print("{} finished!.".format(name))

def kill():
    time.sleep(3)
    raise TimeoutError("No more time!")

kill_thread = threading.Thread(target=kill)
kill_thread.start()

may_take_a_long_time("A", 2)
may_take_a_long_time("B", 2)
may_take_a_long_time("C", 2)
may_take_a_long_time("D", 2)
Run Code Online (Sandbox Code Playgroud)

这输出:

A started...
A finished!.
B started...
Exception in thread Thread-1:
Traceback (most recent call last):
    File "C:\Program Files\Python35\lib\threading.py", line 914, in _bootstrap_inner
    self.run()
    File "C:\Program Files\Python35\lib\threading.py", line 862, in run
    self._target(*self._args, **self._kwargs)
    File "timeout.py", line 11, in kill
    raise TimeoutError("No more time!")
    TimeoutError: No more time!

B finished!.
C started...
C finished!.
D started...
D finished!.
Run Code Online (Sandbox Code Playgroud)

这甚至可以远程实现吗?我意识到我可以这样做:

import threading
import time

def may_take_a_long_time(name, wait_time, thread):
    if not thread.is_alive():
        return
    print("{} started...".format(name))
    time.sleep(wait_time)
    print("{} finished!.".format(name))

def kill():
    time.sleep(3)
    raise TimeoutError("No more time!")

kill_thread = threading.Thread(target=kill)
kill_thread.start()

may_take_a_long_time("A", 2, kill_thread)
may_take_a_long_time("B", 2, kill_thread)
may_take_a_long_time("C", 2, kill_thread)
may_take_a_long_time("D", 2, kill_thread)
Run Code Online (Sandbox Code Playgroud)

但是,例如,如果may_take_a_long_time("B", 60, kill_thread)调用此方法,则此方法失败.

所以我想我的TL; DR问题是,对主线程本身设置时间限制的最佳方法是什么?

For*_*Bru 7

你可以使用_thread.interrupt_main(这个模块thread在Python 2.7中调用):

import time, threading, _thread

def long_running():
    while True:
        print('Hello')

def stopper(sec):
    time.sleep(sec)
    print('Exiting...')
    _thread.interrupt_main()

threading.Thread(target = stopper, args = (2, )).start()

long_running()
Run Code Online (Sandbox Code Playgroud)


rba*_*ffy 5

如果父线程是根线程,您可能想尝试os._exit(0).

import os
import threading
import time

def may_take_a_long_time(name, wait_time):
    print("{} started...".format(name))
    time.sleep(wait_time)
    print("{} finished!.".format(name))

def kill():
    time.sleep(3)
    os._exit(0)

kill_thread = threading.Thread(target=kill)
kill_thread.start()

may_take_a_long_time("A", 2)
may_take_a_long_time("B", 2)
may_take_a_long_time("C", 2)
may_take_a_long_time("D", 2)
Run Code Online (Sandbox Code Playgroud)