多线程threading模块(二)daemon和join的区别
  Tnoh9YphLzNA 2023年11月17日 38 0

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
### 主线程结束 ###


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月17日 0

暂无评论

推荐阅读
  wtcU0l7oJED3   2023年12月23日   30   0   0 多线程Java多线程Java
Tnoh9YphLzNA