我想创建一些线程来向数组中添加一些东西,但是,如果它们在2秒内没有完成,我想终止它们。
这是一个概念教授,所以代码很简单。每秒钟我都希望一个线程将该项添加到列表中,因此线程会在0、1、2、3和4秒后运行。这个想法是不让线程3和4运行。
import threading, time
myList = []
def foo(value):
global myList
time.sleep(value)
print("Value: {}".format(value))
myList.append(value)
threads = []
for i in range(5):
th = threading.Thread(target=foo, args=(i,))
threads.append(th)
for th in threads:
th.start()
我现在该怎么办?我试着使用其他一些逻辑,比如使用
th.join(timeout)
但这似乎并不奏效。
正如我在评论中所说,你真的不能"杀死";螺纹(外部(。然而,它们可以";自杀;通过返回或引发异常。
下面是当线程的执行时间超过给定的时间量时执行后者的示例。请注意,这与执行join(timeout)
调用不同,后者只会阻塞,直到线程结束或经过指定的时间量。这就是为什么无论线程是否在对join()
的调用超时之前完成,都会打印value
并将其附加到列表中。
我从题为"杀死线程的不同方法"的教程中获得了使用sys.settrace()
的基本想法——尽管我的实现略有不同。还要注意,这种方法可能会引入大量的开销。
import sys
import threading
import time
class TimelimitedThread(threading.Thread):
def __init__(self, *args, time_limit, **kwargs):
self.time_limit = time_limit
self._run_backup = self.run # Save superclass run() method.
self.run = self._run # Change it to custom version.
super().__init__(*args, **kwargs)
def _run(self):
self.start_time = time.time()
sys.settrace(self.globaltrace)
self._run_backup() # Call superclass run().
self.run = self._run_backup # Restore original.
def globaltrace(self, frame, event, arg):
return self.localtrace if event == 'call' else None
def localtrace(self, frame, event, arg):
if(event == 'line' and
time.time()-self.start_time > self.time_limit): # Over time?
raise SystemExit() # Terminate thread.
return self.localtrace
THREAD_TIME_LIMIT = 2.1 # Secs
threads = []
my_list = []
def foo(value):
global my_list
time.sleep(value)
print("Value: {}".format(value))
my_list.append(value)
for i in range(5):
th = TimelimitedThread(target=foo, args=(i,), time_limit=THREAD_TIME_LIMIT)
threads.append(th)
for th in threads:
th.start()
for th in threads:
th.join()
print('nResults:')
print('my_list:', my_list)
输出:
Value: 0
Value: 1
Value: 2
Results:
my_list: [0, 1, 2]
Join((用于等待各个线程完成。要终止线程,请使用stop((。。您可以尝试以下操作:睡眠时间(N(th.join((