Python Version:3.10.12
案列一:最简洁的情况,在多线程代码中不开启daemon或join功能。
import threading
import time
loop_count = 5
def count_num(num):
print('子线程<{}>开始运行'.format(num))
for x in range(10):
time.sleep(x)
print('子线程<{}>结束运行'.format(num))
return num
task_list = []
for i in range(loop_count):
task = threading.Thread(target=count_num, args=(i,))
task_list.append(task)
print('-'*20)
print('全部多线程开始')
start = time.time()
for task in task_list:
# 开启多线程任务
task.start()
print('全部多线程全部结束')
end = time.time()
ret = end - start
print('全部多线程耗时: {}'.format(ret))
print('### 主线程结束 ###')
运行结果来看,主线程和子线程是完全独立运行的,并不相互依存。默认行情况下,主进程结束并不影响子进程的运行。
全部多线程开始
子线程<0>开始运行
子线程<1>开始运行
子线程<2>开始运行
子线程<3>开始运行
子线程<4>开始运行 # 子线程全部启动
全部多线程全部结束 # 主线程继续向下运行,并不理会子线程的状态
全部多线程耗时: 0.0005412101745605469
### 主线程结束 ### # 主进程不涉及任何计算,所以很快就结束了
子线程<0>结束运行 # 主进程结束后,子线程继续运行至计算结束
子线程<4>结束运行
子线程<1>结束运行
子线程<2>结束运行
子线程<3>结束运行
案例二:在多线程代码中开启daemon
import threading
import time
loop_count = 5
def count_num(num):
print('子线程<{}>开始运行'.format(num))
for x in range(10):
time.sleep(x)
print('子线程<{}>结束运行'.format(num))
return num
task_list = []
for i in range(loop_count):
# 显式的标记 daemon=True
task = threading.Thread(target=count_num, args=(i,), daemon=True)
task_list.append(task)
print('-'*20)
print('全部多线程开始')
start = time.time()
for task in task_list:
# 开启多线程任务
task.start()
print('全部多线程全部结束')
end = time.time()
ret = end - start
print('全部多线程耗时: {}'.format(ret))
print('### 主线程结束 ###')
运行结果没有丢失内容,开启了daemon=True以后,子线程会随着主线程的结束而退出。
全部多线程开始
子线程<0>开始运行
子线程<1>开始运行
子线程<2>开始运行
子线程<3>开始运行
子线程<4>开始运行
全部多线程全部结束
全部多线程耗时: 0.00020813941955566406
### 主线程结束 ###
场景三:在多线程代码中开启join
import threading
import time
loop_count = 5
def count_num(num):
print('子线程<{}>开始运行'.format(num))
for x in range(10):
time.sleep(x)
print('子线程<{}>结束运行'.format(num))
return num
task_list = []
for i in range(loop_count):
# 显式的标记 daemon=True
task = threading.Thread(target=count_num, args=(i,), daemon=True)
task_list.append(task)
print('-'*20)
print('全部多线程开始')
start = time.time()
for task in task_list:
# 开启多线程任务
task.start()
task.join() # 子线程配置一个join(),阻塞主线程下一次的for循环的运行。
# 因此当前子线程结束前,无法启动第二个子线程
print('全部多线程全部结束')
end = time.time()
ret = end - start
print('全部多线程耗时: {}'.format(ret))
print('### 主线程结束 ###')
运行结果与单线程类似,join()会阻塞主线程的运行。即当前的子线程start()运行结束前,主线程不会继续运行下面的代码。本例中,主线程通过for循环来启动子线程。当前的子线程start()运行后,紧跟着有使用了task.join()阻塞住了主线程继续循环启动下一个子线程的start()。因此整个程序运行流程就变成了一个一个顺序运行子线程,与单线程运行流程无异了。
全部多线程开始
子线程<0>开始运行
子线程<0>结束运行
子线程<1>开始运行
子线程<1>结束运行
子线程<2>开始运行
子线程<2>结束运行
子线程<3>开始运行
子线程<3>结束运行
子线程<4>开始运行
子线程<4>结束运行
全部多线程全部结束
全部多线程耗时: 225.15359783172607
### 主线程结束 ###