3.多线程.md
2021/7/7 23:05:45
本文主要是介绍3.多线程.md,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
多线程
多线程 - 进程与线程
- 多线程---并发
- Threading模块
- 多线程基础
- io密集型
- 计算密集型
- 守护线程:
进程与线程
-
进程:指在系统中运行的一个应用程序,程序一旦运行就是进程;
- 进程:资源分配的最小单位,一个进程至少有一个线程
- 线程、内存、文件、网络句柄
- 内存:每个进程的内存是相互独立的
- 文件/网络句柄:他们是所有的进程所共有的,例如打开同一个文件,取抢同一个网络端口,这样的操作是被允许的
- 抢占资源,导致死锁
- 进程:资源分配的最小单位,一个进程至少有一个线程
-
线程:系统分配处理器时间资源的基本单位,或者说进程之内独立执行的一个单元的执行流。
- 线程:程序执行的最小单位
-
汇总:
- 1、进程要分配一大部分的内存,而线程只需要分配一部分栈就可以了
- 2、一个程序至少有一个进程,一个进程至少有一个线程
- 3、进程是资源分配的最小单位,线程是程序执行的最小单位
- 4、一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行
多线程---并发
-
并行:两个CPU同时做事情
-
并发:一个cpu,从执行A任务,接着执行b任务,又执行a任务,接着又执行b任务,循环执行
- 1、使用线程可以把占据长时间的程序中的任务放到后台去处理
- 2、用户界面可以更加吸引人,比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度
- 程序的运行速度可能加快
- 在一些等待的任务实现上如用户输入,文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等
Threading模块
-
python3线程中常用的两个模块为:
- _thread
- threading(推荐使用)
-
thread模块已经被废弃了。用户可以使用threading模块代替。所以,在python3中不能再使用thread模块,为了兼容性,python3将thread重命名为_thread
-
常用方法
- run():用以表示线程活动的方法
- start():启动线程的方法
- join([time]):等待至线程中止,这阻塞调用线程直至线程的join()方法被调用中止--正常退出或者抛出未处理的异常--或者是可选的超时发生
- isAlive():返回线程是否活动的
- getName():返回线程名
- setName():设置线程名
- threading.currentThread():返回当前的线程变量
- threading.enumerate():返回一个包含正在运行的线程list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
- threading.activeCount():返回正在运行的线程数量,与len(threading.enumerate())有相同的效果
多线程基础
import time def doing(something): time.sleep(2) print('正在做>>>',something) start_time =time.time() doing('在上课') doing('在上班') end_time =time.time() print('总共耗时>>>',end_time-start_time) 控制台输出: 正在做>>> 在上课 正在做>>> 在上班 总共耗时>>> 4.010261297225952
io密集型
#------------------------------------------------------------- """ 需求:执行效率低 优化:使用多线程 io密集型 """ #------------------------------------------------------------- def doing(something): print('正在做>>>', something) time.sleep(2) start_time = time.time() #1-创建线程 """ target:函数名 args:函数名对应的实参,元组形式 """ t1=threading.Thread(target=doing,args=('在上课',)) t2=threading.Thread(target=doing,args=('在加班',)) #2-启动线程 t1.start() t2.start() end_time = time.time() print('总共耗时>>>', end_time - start_time) 控制台输出 正在做>>> 在上课 正在做>>> 在加班总共耗时>>> 0.0009598731994628906
分析发现跟预期结果不一致,预期结果是大概是2s,现在是0s
原因:直接启动线程:主线程(main)不等待子线程(t1/t2)完成就结束
优化方案:
3-阻塞主线程
t1.join() t2.join() 控制台输出 正在做>>> 在上课 正在做>>> 在加班 总共耗时>>> 2.0047731399536133
计算密集型
#------------------------------------------------------------- """ 需求:执行效率低 优化:使用多线程 计算密集型 """ #------------------------------------------------------------- def doing(): dataNum=0 for i in range(10000000): dataNum+=1 start_time = time.time() #1-创建线程 """ target:你这个线程是做什么,需要执行的函数名 args:函数名对应的实参,元组形式 直接启动线程:主线程(main)不等待子线程(t1/t2)完成就结束 需求:主线程退出之前需要等待子线程全部执行完 优化:阻塞主线程 串行:总共耗时>>> 1.0268769264221191 """ #t1=threading.Thread(target=doing,args=('在上课',)) #t2=threading.Thread(target=doing,args=('在加班',)) # ##2-启动线程 #t1.start() #t2.start() ##3-阻塞主线程 #t1.join() #t2.join() doing() doing() end_time = time.time() print('总共耗时>>>', end_time - start_time) 控制台输出: 总共耗时>>> 1.0268769264221191
多线程方式;
改变部分的代码
t1=threading.Thread(target=doing) t2=threading.Thread(target=doing) #2-启动线程 t1.start() t2.start() #3-阻塞主线程 t1.join() t2.join() 控制台输出 总共耗时>>> 1.0593979358673096
通过对比发现对应计算密集型来说,使用串行和多线程,耗时一样
对于cpython解释器GIL(全局解释器锁)),不管多少核 cpu同一时间只能处理一件事
原因:
多线程是并发:并发是来回切换执行不同的任务,导致计算密集型执行的时间比串行还长,因为来回切换也需要耗时
守护线程:
#------------------------------------------------------------- """ 需求:执行效率低 优化:使用多线程 守护线程 主线程想满足一个条件就退出,使用多线程直接不能直接退出主线程 """ #------------------------------------------------------------- def doing(): while True: print('我在doing') time.sleep(1) start_time = time.time() #1-创建线程 """ target:你这个线程是做什么,需要执行的函数名 args:函数名对应的实参,元组形式 直接启动线程:主线程(main)不等待子线程(t1/t2)完成就结束 需求:主线程退出之前需要等待子线程全部执行完 优化:阻塞主线程 串行:总共耗时>>> 1.0268769264221191 """ t1=threading.Thread(target=doing) t2=threading.Thread(target=doing) #2-启动线程 t1.start() t2.start() #3-阻塞主线程 #t1.join() #t2.join() end_time = time.time() for i in range(3): print('**********主线程正在执行*******') print('**********主线程结束*******') print('总共耗时>>>', end_time - start_time) 控制台输出: 死循环 我在doing 我在doing**********主线程正在执行******* **********主线程正在执行******* **********主线程正在执行******* **********主线程结束******* 总共耗时>>> 0.0009987354278564453 我在doing我在doing 我在doing我在doing 我在doing我在doing 我在doing我在doing 我在doing我在doing
分析:
主线程一直无法退出
优化:
增加守护线程 setdaemon(True)
在以下位置增加守护部分代码
t1=threading.Thread(target=doing) t2=threading.Thread(target=doing) t1.setDaemon(True)#守护 t2.setDaemon(True) #2-启动线程 t1.start() t2.start() 控制台输出 我在doing 我在doing **********主线程正在执行******* **********主线程正在执行******* **********主线程正在执行******* **********主线程结束******* 总共耗时>>> 0.0009744167327880859
这篇关于3.多线程.md的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现
- 2024-06-03为什么以及如何要进行架构设计权衡?
- 2024-05-31全网首发第二弹!软考2024年5月《软件设计师》真题+解析+答案!(11-20题)
- 2024-05-31全网首发!软考2024年5月《软件设计师》真题+解析+答案!(21-30题)