Python之路,Day9 - 线程、进程、协程和IO多路复用
參考博客:
線程、進(jìn)程、協(xié)程:
http://www.cnblogs.com/wupeiqi/articles/5040827.html
http://www.cnblogs.com/alex3714/articles/5230609.html
IO多路復(fù)用:
http://www.cnblogs.com/wupeiqi/articles/5040823.html
?課堂筆記:
- 線程進(jìn)程介紹
1. 工作最小單元是線程
2. 應(yīng)用程序 -> 至少有一個進(jìn)程 -> 至少有一個線程
3. 應(yīng)用場景:
IO密集型:線程
計算密集型:進(jìn)程
4. GIL,全局解釋器鎖。
- 保證同一個進(jìn)程中只有一個線程同時被調(diào)度
- 線程
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. 線程池
模式一:直接處理
def task(url):
"""
任務(wù)執(zhí)行兩個操作:下載;保存本地
"""
# response中封裝了Http請求響應(yīng)的所有數(shù)據(jù)
# - response.url 請求的URL
# - response.status_code 響應(yīng)狀態(tài)碼
# - response.text 響應(yīng)內(nèi)容(字符串格式)
# - response.content 響應(yīng)內(nèi)容(字節(jié)格式)
# 下載
response = requests.get(url)
# 下載內(nèi)容保存至本地
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()
# 下載內(nèi)容保存至本地
f = open('a.log','wb')
f.write(response.content)
f.close()
def task(url):
"""
只做下載 requests
"""
# response中封裝了Http請求響應(yīng)的所有數(shù)據(jù)
# - response.url 請求的URL
# - response.status_code 響應(yīng)狀態(tài)碼
# - response.text 響應(yīng)內(nèi)容(字符串格式)
# - response.content 響應(yīng)內(nèi)容(字節(jié)格式)
# 下載
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中包含response
future = pool.submit(task,url)
# 下載成功后,自動調(diào)用save方法
future.add_done_callback(save)
- 進(jìn)程
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 = False
p.start()
p.join(1)
print('主進(jìn)程最后...')
2. 進(jìn)程之間的數(shù)據(jù)共享
特殊的東西
- Array(‘類型’,長度)
- Manager().list() / Manager().dict()
3. 進(jìn)程池
================== 結(jié)論 ==================
IO密集:線程
計算密集:進(jìn)程
- 協(xié)程
pip3 install greenlet
協(xié)程永遠(yuǎn)是一個線程在執(zhí)行,對線程的一個分片處理。
二次加工:
自定義:
select實(shí)現(xiàn)
現(xiàn)成 :
pip3 install gevent
- IO多路復(fù)用
監(jiān)聽多個socket對象是否有變化(可讀,可寫,發(fā)送錯誤)
- 示例一:
- socketserverIO
- IO多路復(fù)用
- 線程
- 自定義異步非阻塞的框架
本周作業(yè):
服務(wù)端:socketserver
用IO多路復(fù)用select,使用“偽”并發(fā)
客戶端:
基本操作:
聊天
上傳
嘗試:
客戶端是否可以用select來實(shí)現(xiàn)???
轉(zhuǎn)載于:https://www.cnblogs.com/liyongsan/p/6580256.html
總結(jié)
以上是生活随笔為你收集整理的Python之路,Day9 - 线程、进程、协程和IO多路复用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: -webkit-
- 下一篇: 1028. 人口普查(20)