在 Python 的多线程编程中,在实例代码中经常有 thread1.join()这样的代码。那么今天咱们用实际代码来解释一下 join 函数的作用。
join的原理就是依次检验线程池中的线程是否结束,没有结束就阻塞直到线程结束,如果结束则跳转执行下一个线程的join函数。
先看看这个:
1. 阻塞主进程,专注于执行多线程中的程序。
# 测试多线程中join的功能
import threading, time
def doWaiting():
print('thread %s is running345...' % threading.current_thread().name)
print ('start waiting1: ' + time.strftime('%H:%M:%S') + "\n" )
time.sleep(10)
print ('stop waiting1: ' + time.strftime('%H:%M:%S') + "\n")
def doWaiting1():
print('thread %s is running567' % threading.current_thread().name)
print( 'start waiting2: ' + time.strftime('%H:%M:%S') + "\n" )
time.sleep(8)
print ('stop waiting2: ', time.strftime('%H:%M:%S') + "\n" )
print('thread %s is running123...' % threading.current_thread().name)
tsk = []
thread1 = threading.Thread(target = doWaiting,name='thread1')
thread1.start()
thread1.join()
print('thread %s is running123...' % threading.current_thread().name)
tsk.append(thread1)
thread2 = threading.Thread(target = doWaiting1,name='thread2')
thread2.start()
# thread2.join()
tsk.append(thread2)
print ('start join: ' + time.strftime('%H:%M:%S') + "\n" )
# for tt in tsk:
# tt.start()
# tt.join()
print ('end join: ' + time.strftime('%H:%M:%S') + "\n")
结果
thread MainThread is running123...
thread thread1 is running345...
start waiting1: 23:49:23
stop waiting1: 23:49:33
thread MainThread is running123...
thread thread2 is running567
start waiting2: 23:49:33
start join: 23:49:33
end join: 23:49:33
stop waiting2: 23:49:41
2. 多线程多join的情况下,依次执行各线程的join方法,前头一个结束了才能执行后面一个。
3. 无参数,则等待到该线程结束,才开始执行下一个线程的join。
import threading, time
def doWaiting():
print ('start waiting1: ' + time.strftime('%H:%M:%S') + "\n" )
time.sleep(10)
print ('stop waiting1: ' + time.strftime('%H:%M:%S') + "\n")
def doWaiting1():
print( 'start waiting2: ' + time.strftime('%H:%M:%S') + "\n" )
time.sleep(8)
print ('stop waiting2: ', time.strftime('%H:%M:%S') + "\n" )
tsk = []
thread1 = threading.Thread(target = doWaiting)
thread1.start()
thread1.join()
tsk.append(thread1)
thread2 = threading.Thread(target = doWaiting1)
thread2.start()
tsk.append(thread2)
print ('start join: ' + time.strftime('%H:%M:%S') + "\n" )
# for tt in tsk:
# tt.join()
print ('end join: ' + time.strftime('%H:%M:%S') + "\n")
结果
start waiting1: 23:31:50
stop waiting1: 23:32:00
start waiting2: 23:32:00
start join: 23:32:00
4. 参数timeout为线程的阻塞时间,如 timeout=6 就是执行这个线程6s 以后,就不管他了,继续执行下面的代码。
import threading, time
def doWaiting():
print ('start waiting1: ' + time.strftime('%H:%M:%S') + "\n" )
time.sleep(10)
print ('stop waiting1: ' + time.strftime('%H:%M:%S') + "\n")
def doWaiting1():
print( 'start waiting2: ' + time.strftime('%H:%M:%S') + "\n" )
time.sleep(8)
print ('stop waiting2: ', time.strftime('%H:%M:%S') + "\n" )
tsk = []
thread1 = threading.Thread(target = doWaiting)
thread1.start()
thread1.join(6)
tsk.append(thread1)
thread2 = threading.Thread(target = doWaiting1)
thread2.start()
tsk.append(thread2)
print ('start join: ' + time.strftime('%H:%M:%S') + "\n" )
# for tt in tsk:
# tt.join()
print ('end join: ' + time.strftime('%H:%M:%S') + "\n")
结果
start waiting1: 23:30:56
start waiting2: 23:31:02
start join: 23:31:02
end join: 23:31:02
注意thread.start(),thread.join()要连着用才能体现出join()阻塞线程的作用
# 测试多线程中join的功能
import threading, time
def doWaiting():
print ('start waiting1: ' + time.strftime('%H:%M:%S') + "\n" )
time.sleep(10)
print ('stop waiting1: ' + time.strftime('%H:%M:%S') + "\n")
def doWaiting1():
print( 'start waiting2: ' + time.strftime('%H:%M:%S') + "\n" )
time.sleep(8)
print ('stop waiting2: ', time.strftime('%H:%M:%S') + "\n" )
tsk = []
thread1 = threading.Thread(target = doWaiting)
thread1.start()
# thread1.join()
tsk.append(thread1)
thread2 = threading.Thread(target = doWaiting1)
thread2.start()
tsk.append(thread2)
print ('start join: ' + time.strftime('%H:%M:%S') + "\n" )
for tt in tsk:
# tt.start()
tt.join()
print ('end join: ' + time.strftime('%H:%M:%S') + "\n")
start waiting1: 23:39:12
start waiting2: 23:39:12
start join: 23:39:12
stop waiting2: 23:39:20
stop waiting1: 23:39:22
end join: 23:39:22
本来我们想的是thread1完全执行完了,再执行thread2,但事实是因为thread2 sleep了8秒更早结束了,然后thread1 sleep了10才结束
再看看连着的
# 测试多线程中join的功能
import threading, time
def doWaiting():
print ('start waiting1: ' + time.strftime('%H:%M:%S') + "\n" )
time.sleep(10)
print ('stop waiting1: ' + time.strftime('%H:%M:%S') + "\n")
def doWaiting1():
print( 'start waiting2: ' + time.strftime('%H:%M:%S') + "\n" )
time.sleep(8)
print ('stop waiting2: ', time.strftime('%H:%M:%S') + "\n" )
tsk = []
thread1 = threading.Thread(target = doWaiting)
# thread1.start()
# thread1.join()
tsk.append(thread1)
thread2 = threading.Thread(target = doWaiting1)
# thread2.start()
tsk.append(thread2)
print ('start join: ' + time.strftime('%H:%M:%S') + "\n" )
for tt in tsk:
tt.start()
tt.join()
print ('end join: ' + time.strftime('%H:%M:%S') + "\n")
结果
start join: 23:42:34
start waiting1: 23:42:34
stop waiting1: 23:42:44
start waiting2: 23:42:44
stop waiting2: 23:42:52
end join: 23:42:52