我需要在程序中对数据进行一些网络调用。我打算并行调用它们,但并非所有这些都需要完成。
我现在拥有的是
thread1 = makeNetworkCallThread()
thread1.start()
thread2 = makeLongerNetworkCallThread()
thread2.start()
thread1.join()
foo = thread1.getData()
thread2.join()
if conditionOn(foo):
foo = thread2.getData()
# continue with code
问题在于即使较短的网络呼叫成功,我也需要等待更长的网络呼叫完成所需的时间
如果我在if语句中移动thread2.join()会发生什么?可能永远不会调用join方法。这会导致过时的线程等问题吗?
答案 0 :(得分:0)
thread2
仍会继续投放(受GIL的警告影响,但因为这是一个可能不关心的网络电话)join
是是否打电话。区别在于主要上下文在继续执行其他操作之前是否等待线程结束 - 如果您在没有完成更长时间的网络调用的情况下能够继续处理,那么应该没有问题。
请记住,在完成所有线程之前,程序实际上不会结束(解释器不会退出)。根据这个长时间网络调用对程序其余部分运行时间的延迟(如果你不等待),可能看起来程序到达目的但实际上并没有直到网络电话结束了。考虑一下这个愚蠢的例子:
# Python 2.7
import threading
import time
import logging
def wasteTime(sec):
logging.info('Thread to waste %d seconds started' % sec)
time.sleep(sec)
logging.info('Thread to waste %d seconds ended' % sec)
if __name__ == '__main__':
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
t1 = threading.Thread(target=wasteTime, args=(2,))
t2 = threading.Thread(target=wasteTime, args=(10,))
t1.start()
t2.start()
t1.join()
logging.info('Main context done')
这是日志记录输出:
$ time python test.py
2015-01-15 09:32:12,239 Thread to waste 2 seconds started
2015-01-15 09:32:12,239 Thread to waste 10 seconds started
2015-01-15 09:32:14,240 Thread to waste 2 seconds ended
2015-01-15 09:32:14,241 Main context done
2015-01-15 09:32:22,240 Thread to waste 10 seconds ended
real 0m10.026s
user 0m0.015s
sys 0m0.010s
请注意,虽然主要上下文在2秒后完成(thread1
完成所花费的时间),但程序在thread2
完成之前不会完全退出(开始执行后十秒钟)。在这种情况下(特别是如果输出被记录),我认为最好在某个时刻显式调用join
并在日志中明确标识这是程序的内容这样做是为了让用户/操作员看起来没有挂起。对于我的愚蠢示例,这可能看起来像在主要上下文的末尾添加这样的行:
logging.info('Waiting for thread 2 to complete')
t2.join()
这会产生一些不那么神秘的日志输出:
$ time python test.py
2015-01-15 09:39:18,979 Thread to waste 2 seconds started
2015-01-15 09:39:18,979 Thread to waste 10 seconds started
2015-01-15 09:39:20,980 Thread to waste 2 seconds ended
2015-01-15 09:39:20,980 Main context done
2015-01-15 09:39:20,980 Waiting for thread 2 to complete
2015-01-15 09:39:28,980 Thread to waste 10 seconds ended
real 0m10.027s
user 0m0.015s
sys 0m0.010s