当我不显式调用join方法时,线程会发生什么?

时间:2015-01-15 12:13:11

标签: multithreading python-2.7

我需要在程序中对数据进行一些网络调用。我打算并行调用它们,但并非所有这些都需要完成。

我现在拥有的是

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方法。这会导致过时的线程等问题吗?

1 个答案:

答案 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