日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

10-线程,进程,协程,IO多路复用

發布時間:2025/3/15 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 10-线程,进程,协程,IO多路复用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
- 線程進程介紹
1. 工作最小單元是線程
2. 應用程序 -> 至少有一個進程 -> 至少有一個線程
3. 應用場景:
IO密集型:線程
計算密集型:進程
4. GIL,全局解釋器鎖。
- 保證同一個進程中只有一個線程同時被調度
- 線程
1. 基本使用 def task(arg):time.sleep(arg)print(arg) for i in range(5):t = threading.Thread(target=task,args=[i,])# t.setDaemon(True) # 主線程終止,不等待子線程# t.setDaemon(False)t.start()# t.join() # 一直等# t.join(1) # 等待最大時間 2. 鎖 # 1. 只能有一個人使用鎖# lock = threading.Lock() # 只能開一把# lock = threading.RLock()# 可以開多把 # 2. 多個人同時使用鎖# lock = threading.BoundedSemaphore(3) # 3. 所有的解脫鎖的限制# lock = threading.Event() # 4. 肆意妄為# lock = threading.Condition() 3. 線程池
模式一:直接處理 3. 線程池模式一:直接處理 def task(url):"""任務執行兩個操作:下載;保存本地"""# response中封裝了Http請求響應的所有數據# - response.url 請求的URL# - response.status_code 響應狀態碼# - response.text 響應內容(字符串格式)# - response.content 響應內容(字節格式)# 下載response = requests.get(url)# 下載內容保存至本地f = open('a.log','wb')f.write(response.content)f.close() pool = ThreadPoolExecutor(2) url_list = ['http://www.oldboyedu.com','http://www.autohome.com.cn','http://www.baidu.com', ] for url in url_list:print('開始請求',url)# 去連接池中獲取鏈接pool.submit(task,url) 模式二:分步處理 模式二:分步處理 def save(future):"""只做保存 # future中包含response"""response = future.result()# 下載內容保存至本地f = open('a.log','wb')f.write(response.content)f.close() def task(url):"""只做下載 requests"""# response中封裝了Http請求響應的所有數據# - response.url 請求的URL# - response.status_code 響應狀態碼# - response.text 響應內容(字符串格式)# - response.content 響應內容(字節格式)# 下載response = requests.get(url)return response pool = ThreadPoolExecutor(2) url_list = ['http://www.oldboyedu.com','http://www.autohome.com.cn','http://www.baidu.com', ] for url in url_list:print('開始請求',url)# 去連接池中獲取鏈接# future中包含responsefuture = pool.submit(task,url)# 下載成功后,自動調用save方法future.add_done_callback(save) - 進程
1. 基本使用 from multiprocessing import Process import time def task(arg):time.sleep(arg)print(arg) if __name__ == '__main__':for i in range(10):p = Process(target=task,args=(i,))p.daemon = True# p.daemon = Falsep.start()p.join(1)print('主進程最后...') 進程鎖和線程鎖是一樣的(使用方式一樣) 2. 進程之間的數據共享
特殊的東西
- Array(‘類型’,長度)
- Manager().list() / Manager().dict()
- 報錯是因為,主進程走完了,子進程就就會報錯
- 寫一個input或者什么的,讓主進程等,就能防止報錯
- 或者jion成為串行。
- 使用進程池,就可以避免
- 第三方工具 from multiprocessing import Process from threading import Thread""" # 驗證進程之間數據不共享 def task(num,li):li.append(num)print(li) # 數據不是共享的,打印出來就是一個個數字 [1] [2] 。。。if __name__ == '__main__':v = []for i in range(10):# p = Process(target=task,args=(i,v,))p = Thread(target=task,args=(i,v,))p.start() """""" # 方式一:進程數據共享 from multiprocessing import Process,Array from threading import Threaddef task(num,li):li[num] = 1print(list(li))if __name__ == '__main__':v = Array('i',10) # v[0]for i in range(10):p = Process(target=task,args=(i,v,))p.start() """ from multiprocessing import Process,Manager from threading import Threaddef task(num,li):li.append(num)print(li)if __name__ == '__main__':v = Manager().list()# v = Manager().dict()for i in range(10):p = Process(target=task,args=(i,v,))p.start()# p.join()input('>>>') 3. 進程池 - from concurrent.futures import ProcessPoolExecutordef call(arg):data = arg.result()print(data)def task(arg):print(arg)return arg + 100if __name__ == '__main__':pool = ProcessPoolExecutor(5)for i in range(10):obj = pool.submit(task,i)obj.add_done_callback(call) ================== 結論 ==================
IO密集:線程
計算密集:進程 - 協程
pip3 install greenlet
協程永遠是一個線程在執行,對線程的一個分片處理。 from greenlet import greenletdef test1():print(12)gr2.switch()print(34)gr2.switch()def test2():print(56)gr1.switch()print(78)gr1 = greenlet(test1) gr2 = greenlet(test2) gr1.switch()
二次加工:
自定義:
select實現
現成 :
pip3 install gevent from gevent import monkey; monkey.patch_all() import gevent import requestsdef f(url):response = requests.get(url)print(response.url,response.status_code)gevent.joinall([gevent.spawn(f, 'http://www.oldboyedu.com/'),gevent.spawn(f, 'http://www.baidu.com/'),gevent.spawn(f, 'http://github.com/'), ]) - IO多路復用
監聽多個socket對象是否有變化(可讀,可寫,發生錯誤(異常))
- 示例一: import socket import select# IO多路復用:8002,8001 # ############################### 基于select實現服務端的“偽”并發 ############################### sk1 = socket.socket() sk1.bind(('127.0.0.1',8001,)) sk1.listen(5)sk2 = socket.socket() sk2.bind(('127.0.0.1',8002,)) sk2.listen(5) inputs = [sk1,sk2,] w_inputs = [] while True:# IO多路復用,同時監聽多個socket對象# - select,內部進行循環操作(1024) 主動查看# - poll, 內部進行循環操作 主動查看# - epoll, 被動告知r,w,e = select.select(inputs,w_inputs,inputs,0.05) # r: readble w: writable e:異常# r = [sk2,]# r = [sk1,]# r = [sk1,sk2]# r = []# r = [conn,]# r = [sk1,Wconn]#######?for obj in r:if obj in [sk1,sk2]:# 新連接撿來了...print('新連接來了:',obj)conn,addr = obj.accept()inputs.append(conn)else:# 有連接用戶發送消息來了..print('有用戶發送數據了:',obj)try:data = obj.recv(1024)except Exception as ex:data = ""if data:w_inputs.append(obj)# obj.sendall(data)else:obj.close()inputs.remove(obj)w_inputs.remove(obj)for obj in w:obj.sendall(b'ok')w_inputs.remove(obj)# Socket對象 sk1 = socket.socket() sk1.bind(('127.0.0.1',8001,)) sk1.listen(5) while True:# conn Socket對象,conn,addr = sk.accept()conn.recv()conn.sendall()

- socketserverIO
- IO多路復用
- 線程 import socket import select import threading# IO多路復用:8002,8001 # ############################### 基于select實現服務端的“偽”并發 ############################### """ def process_request(conn):while True:v = conn.recv(1024)conn.sendall(b'1111')sk1 = socket.socket() sk1.bind(('127.0.0.1',8001,)) sk1.listen(5) inputs=[sk1,] while True:# IO多路復用,同時監聽多個socket對象# - select,內部進行循環操作(1024) 主動查看# - poll, 內部進行循環操作 主動查看# - epoll, 被動告知r,w,e = select.select(inputs,[],inputs,0.05)for obj in r:if obj in sk1:# conn客戶端的socketconn,addr = obj.accept()t = threading.Thread(target=process_request,args=(conn,))t.start() """ # import socketserver # # class MyHandler(socketserver.BaseRequestHandler): # def handle(self): # pass # # # server = socketserver.ThreadingTCPServer(('127.0.0.1',8001),MyHandler) # server.serve_forever()
- 自定義異步非阻塞的框架 ? ? ? ? ?

?

轉載于:https://www.cnblogs.com/can-H/articles/6610683.html

總結

以上是生活随笔為你收集整理的10-线程,进程,协程,IO多路复用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。