Python爬蟲之多進程淺談
一、進程及狀態
1、進程
程序,是指靜態,而進程則是動態的概念,首先把程序運行起來,代碼+涉及的資源=進程,它是操作系統分配資源的基本單位,多進程可以實現多任務
2、進程的狀態
1、就緒態:一切準備好,只等待CPU的調度
2、運行態:CPU正在執行本進程的代碼
3、等待態:等待某個條件的滿足,比如sleep,socket.recvfrom,互斥鎖的解鎖,等待紅綠燈,條件滿足則進入就緒態
二、進程的創建-multiprocessing(重點)
1、multiprocessing模塊介紹:multiprocessing模塊就是跨平臺版本的多進程模塊,提供了一個Process類來創建進程對象
2、通過multiprocessing模塊創建子進程
實現步驟:
1、導入multiprocessing模塊
2、準備用於封裝任務的函數
3、通過multiprocessing.Process()創建子進程target=function
4、執行子進程
參考代碼如下:
3、獲取進程的id
a>通過Linux命令方式查看進程id:ps -aux | grep ‘02-’
b>通過代碼方式查看進程id
當前的子進程是有主進程創建的
os.getpid():取得當前進程的id
os.getppid():取得父進程id(創建當前進程的進程id)
print("------in main -----當前進程id=%d,父進程id=%d“%(os.getpid(), os.getppid()))
4. Process語法結構
a> Process([group [, target [, name [, args [, kwargs]]]]])
"""Process初始化參數"""
- target: 目標,指向, 表示子進程要執行的代碼在target指向的函數中
- args:向target指向的函數傳遞不定參數, 以元組類型來封裝這些不定參數
- kwargs:向target指向的函數傳遞關鍵字參數,以字典類型來封裝這些關鍵字參數
b> 進程對象常用的屬性、方法
- process.name: 進程的名稱
- process.pid: 進程的id
- process.start() : 執行進程
- process.is_alive(): 進程是否是活的
- process.join(timeout) : 阻塞當前進程(主進程),等待子進程執行完畢,再解阻塞
# timeout=2 : 最多阻塞主進程2秒,超過2秒,則主進程解阻塞
- process.terminate() :結束子進程的執行
參考代碼: 03-向子進程傳遞參數.py
參考代碼: 04-進程的屬性和方法.py
5. 進程間不共享全局變量
進程間不共享全局變量
參考代碼: 05-進程間不共享全局變量.py
三、進程線程對比
a>功能方面
都能完成多任務
b>定義方面
1. 進程是操作系統進行資源分配和調度的一個基本單位.
2.線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程自己基本上不擁有系統資源,但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源.
c>區別
1. 一個程序至少有一個進程,一個進程至少有一個線程.
2.線程的劃分尺度小於進程(資源比進程少),使得多線程程序的並發性高。
3.進程在執行過程中擁有獨立的內存單元,而多個線程共享內存,從而極大地提高了程序的運行效率
4.線程不能夠獨立執行,必須依存在進程中
d>優缺點
線程和進程在使用上各有優缺點:線程執行開銷小,但不利於資源的管理和保護;而進程正相反
目標的理解: 要實現多任務, 開多線程比開多進程要更好
四、進程間通信-Queue(隊列)
1.隊列介紹
常用的數據結構,采用先進先出原則(fifo: first inter first outer),從隊列的尾部存(put)數據
從隊列的頭部取(get)數據
2. Queue 的使用
a> queue基本使用
- multiprocess.Queue(maxsize=3)
創建隊列對象,maxsize : 設置隊列存數據的上限,假如不設置maxsize, 則沒有上限的要求
- put(item)
向隊列存數據,假如當前隊列滿,則等待
- get()
從隊列取數據,假如當前隊列空,則等待
- full(): 判隊列是否滿
- empty(): 判隊列是否空
參考代碼: 06-隊列queue初體驗.py
b> 使用Queue隊列實現進程間通信
案例需求: 在父進程中創建兩個子進程,一個往Queue裏寫數據p,y,t,h,o,n一個從Queue裏讀取數據,實現進程間通信
參考代碼: 07-通過隊列實現進程間通信.py
五、進程的創建-進程池Pool
1. 進程池作用
控制進程的數量,重復利用進程對象,減少創建和銷毀進程的開銷
2. 進程池體驗
1. multiprocessing.Pool()
創建進程池對象,可以設置進程池的最大值
2. apply_async(func[,args[,kwds]])
apply(func[,args[,kwds]])
申請異步執行任務
- func: 指向要執行的函數
- args:向要執行的函數傳遞可變參數
- kwds:向要執行的函數傳遞命名參數
3. close() : 關閉進程池, 不再接收新的任務請求
4. terminate() : 結束進程池中的所有子進程,
5. join(): 阻塞當前進程(主進程),等到進程池中的所有進程執行完畢後,再解阻塞
提示(拓展):
進程池的子進程都是由主進程創建的
且默認都是守護進程
假如要執行完進程池中子進程的任務
必須做:
pool.close()
pool.join() # 阻塞主進程
參考代碼: 08-進程池體驗.py
3. 進程池中的進程通信
案例需求: 從進程池中子進程,一個往Queue裏寫數據i,t,c,a,s,t一個從Queue裏讀取數據,實現進程池進程間的通信
提示:如果要使用Pool創建進程,就需要使用multiprocessing.Manager()中的Queue(),而不是multiprocessing.Queue()
Python爬蟲之多進程淺談