Python【多线程与多进程】

mac2022-06-30  76

import time,threadingprint("=======串行方式、并行两种方式调用run()函数=======")def run(): print('哈哈哈')#串行for i in range(5): run()#并行for i in range(5): t = threading.Thread(target=run) #实例化了一个线程 t.start()print("======串行、并行方式统计网页下载时间=======")import requests#定义函数,用于发送http请求,获取网页的内容并写入文件data= {}def down_html(file_name,url): start_time = time.time() res = requests.get(url).content open(file_name+'.html','wb').write(res) end_time = time.time() run_time = end_time-start_time data[url] = run_time#定义一个字典,存放要请求的url地址urls = { 'besttest':'http://www.besttest.cn', 'niuniu':'http://www.nnzhp.cn', 'dsx':'http://www.imdsx.cn', 'cc':'http://www.cc-na.cn'}#串行方式下载网页start_time = time.time()for k,v in urls.items(): down_html(k,v)end_time = time.time()run_time = end_time - start_timeprint('串行方式下载总共花时间:',run_time)#并行方式下载网页threads = []start_time = time.time()for k,v in urls.items(): #开启5个子线程,加上进程中有一个默认的主线程,一共是6个线程 t = threading.Thread(target=down_html,args=(k,v)) #多线程的函数如果传参的话,必须得用args t.start() threads.append(t)for t in threads: #1、主线程等待5个子线程执行完毕,主线程接着运行主线程剩余余部分的代码, #2、不加上下面这行代码,则统计的子线程下载时间不对,下载时间取花费时间最长的那个子线程 #3、如果子线程已经运行完毕,调用下方join()方法也不会报错 t.join()end_time = time.time()run_time = end_time - start_timeprint('并行方式下载总共花时间:',run_time)print('并行方式各个网页下载花时间:',data)print("=========守护线程=========")def cry(): time.sleep(3) print('哇哇哇.......')for i in range(3): t = threading.Thread(target=cry) #1、守护线程:只要主线程结束,那么子线程立即结束,不管子线程有没有运行完成。 #2、setDaemon(True)方法把子线程设置成为守护线程 #3、如何避免由于主线程代码运行完毕,而导致子线程被迫也结束运行的问题:在主线程代码部分time.sleep(3),sleep的时间大于3更好 #4、去掉主线程部分的time.sleep(3)代码,如果主线程运行的比子线程快,则会导致子线程运行过程中突然中断 t.setDaemon(True) t.start()print('Done,运行完成。')time.sleep(3)print("========线程锁==========")#线程为什么要加锁:多线程时,保证修改共享数据时有序的修改,不会产生数据修改混乱#在python2里面需要程序员手动加锁,python3里面不加锁也无所谓,默认会自动帮你加锁。num = 1lock = threading.Lock() #申请一把锁def update(): time.sleep(1) global num lock.acquire() #加锁 num+=1 lock.release() #解锁ts = []for i in range(3): t = threading.Thread(target=update) t.start() ts.append(t)[t.join() for t in ts]print('多线程修改全局变量,修改后的值为:',num)print("==========多进程=========")import multiprocessing,threadingdef output(): print('呵呵呵哈哈哈嘿嘿嘿')def execute(num): for i in range(num): t = threading.Thread(target=output) t.start()if __name__ == '__main__': for i in range(5): p = multiprocessing.Process(target=execute,args=(2,)) #启动5个进程,6个线程 p.start()# 问题:为什么python的多线程不能利用多核CPU,但是咱们在写代码的时候,多线程的确是在并发,而且还比单线程快# 原因:因为GIL,python只有一个GIL,运行python时,就要拿到这个锁才能执行,在遇到I/O 操作时会释放这把锁。# 如果是纯计算的程序,没有 I/O 操作,解释器会每隔100次操作就释放这把锁,让别的线程有机会 执行(这个次数可以通sys.setcheckinterval# 来调整)同一时间只会有一个获得GIL线程在跑,其他线程都处于等待状态# 1、如果是CPU密集型代码(循环、计算等),由于计算工作量多和大,计算很快就会达到100,然后触发GIL的释放与在竞争,多个线程来回切换损耗资源,# 所以在多线程遇到CPU密集型代码时,单线程会比较快# 2、如果是I\O密集型代码(文件处理、网络爬虫),开启多线程实际上是并发(不是并行),IO操作会进行IO等待,线程A等待时,自动切换到线程B,# 这样就提升了效率

转载于:https://www.cnblogs.com/mtszw/p/9123157.html

最新回复(0)