显而易见的解决方案是通过在构造函数/启动时将其传递给线程对象/函数来共享某种可变变量。
执行此操作的简洁方法是构建一个具有适当实例属性的类。如果您使用的是threading.Thread
subclass https://docs.python.org/2/library/threading.html#thread-objects,您通常可以使用子类本身作为粘贴这些属性的地方,而不仅仅是一个线程函数。但我会用一个来展示它list
只是因为它更短:
def test_a_func(thread_state):
# ...
thread_state[0] = my_error_state
# ...
def main_thread():
test_states = [None]
test_a = threading.Thread(target=test_a_func, args=(test_states,))
test_a.start()
您还可以(并且通常想要)打包Lock
or Condition
进入可变状态对象,这样你就可以在之间正确同步main_thread
and test_a
.
(另一种选择是使用queue.Queue
, an os.pipe
等来传递信息,但您仍然需要将该队列或管道传递给子线程 - 您的操作方式与上面完全相同。)
但是,值得考虑您是否真的需要这样做。如果你想到test_a
and test_b
作为“作业”,而不是“线程函数”,您可以在池上执行这些作业,并让池处理返回的结果或错误。
例如:
try:
with concurrent.futures.ThreadPoolExecutor(workers=2) as executor:
tests = [executor.submit(job) for job in (test_a, test_b)]
for test in concurrent.futures.as_completed(tests):
result = test.result()
except Exception as e:
# do stuff
现在,如果test_a
函数引发异常,主线程将得到该异常——并且,因为这意味着退出with
阻塞,所有其他作业都被取消并丢弃,并且工作线程关闭。
如果您使用的是 2.5-3.1,则没有concurrent.futures
内置,但您可以安装PyPI 的向后移植 https://pypi.python.org/pypi/futures,或者你可以重写一些东西multiprocessing.dummy.Pool
. (It's slightly这样会更复杂,因为您必须创建一系列作业并调用map_async
返回一个迭代器AsyncResult
对象……但实际上这仍然很简单。)