進程相關
一.進程和線程的區別 或者GIL鎖
1.進程是cpu資源分配的最小單元
線程是cpu計算的最小單元
2.一個進程中可以有多個線程
3.對於python來說他的進程和線程和其他語言有差異, 是有GIL鎖.
GIL鎖保證一個進程中同一時刻只有一個線程被cpu調度.
IO密集型操作可以使用多線程, 計算密集型操作可以使用多進程.
二.進程
進程(Process)是計算機中的程序關於某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位,是操作系統結構的基礎。在早期面向進程設計的計算機結構中,進程是程序的基本執行實體;在當代面向線程設計的計算機結構中,進程是線程的容器。程序是指令、數據及其組織形式的描述,進程是程序的實體。
操作系統引入進程的概念的原因
從理論角度看,是對正在運行的程序過程的抽象;
從實現角度看,是一種數據結構,目的在於清晰地刻畫動態系統的內在規律,有效管理和調度進入計算機系統主存儲器運行的程序。
進程的特征
動態性:進程的實質是程序在多道程序系統中的一次執行過程,進程是動態產生,動態消亡的。
並發性:任何進程都可以同其他進程一起並發執行
獨立性:進程是一個能獨立運行的基本單位,同時也是系統分配資源和調度的獨立單位;
異步性:由於進程間的相互制約,使進程具有執行的間斷性,即進程按各自獨立的、不可預知的速度向前推進
結構特征:進程由程序、數據和進程控制塊三部分組成。
多個不同的進程可以包含相同的程序:一個程序在不同的數據集裏就構成不同的進程,能得到不同的結果;但是執行過程中,程序不能發生改變。
進程與程序的區別
程序是指令和數據的有序集合,其本身沒有任何運行的含義,是一個靜態的概念。
而進程是程序在處理機上的一次執行過程,它是一個動態的概念。
程序可以作為一種軟件資料長期存在,而進程是有一定生命期的。
程序是永久的,進程是暫時的。
進程間的數據不共享
1.進程間的通信應該盡量避免共享數據的方式
2.進程間的數據是獨立的,可以借助隊列或管道實現通信,二者都是基於消息傳遞的。雖然進程間數據獨立,但可以用過Manager實現數據共享
import multiprocessing data_list = [] def task(arg): data_list.append(arg)print(data_list) def run(): for i in range(10): p = multiprocessing.Process(target=task, args=(i,)) # p = threading.Thread(target=task,args=(i,)) p.start() if __name__ == ‘__main__‘: run() #結果 [2] [0] [1] [3] [8] [5] [6] [7] [4] [9]
進程的常用功能
join
deamon
name
multiprocessing.current_process()
multiprocessing.current_process().ident/pid
import time import multiprocessing def task(arg): p = multiprocessing.current_process() print(p.name) time.sleep(2) print(arg) def run(): print(‘111111111‘) p1 = multiprocessing.Process(target=task,args=(1,)) p1.name = ‘pp1‘ p1.start() print(‘222222222‘) p2 = multiprocessing.Process(target=task, args=(2,)) p2.name = ‘pp2‘ p2.start() print(‘333333333‘) if __name__ == ‘__main__‘: run() #結果:111111111 222222222 333333333 pp1 pp2 1 2
通過類繼承方式創建進程
import multiprocessing class MyProcess(multiprocessing.Process): def run(self): print(‘當前進程‘,multiprocessing.current_process()) def run(): p1 = MyProcess() p1.start() p2 = MyProcess() p2.start() if __name__ == ‘__main__‘: run() #結果:當前進程 <MyProcess(MyProcess-1, started)> 當前進程 <MyProcess(MyProcess-2, started)>
進程間的數據共享
進程之間的通信有兩種實現方式:管道和隊列
from multiprocessing import Manager,Process,Lock def work(dic,mutex): # mutex.acquire() # dic[‘count‘]-=1 # mutex.release() # 也可以這樣加鎖 with mutex: dic[‘count‘] -= 1 if __name__ == ‘__main__‘: mutex = Lock() m = Manager() #實現共享,由於字典是共享的字典,所以得加個鎖 share_dic = m.dict({‘count‘:100}) p_l = [] for i in range(100): p = Process(target=work,args=(share_dic,mutex)) p_l.append(p) #先添加進去 p.start() for i in p_l: i.join() print(share_dic) # 共享就意味著會有競爭,
三.進程鎖
Lock
RLock
import time import threading import multiprocessing lock = multiprocessing.RLock() def task(arg): print(‘鬼子來了‘) lock.acquire() time.sleep(2) print(arg) lock.release() if __name__ == ‘__main__‘: p1 = multiprocessing.Process(target=task, args=(1,)) p1.start() p2 = multiprocessing.Process(target=task, args=(2,)) p2.start()
為什麽要加鎖
因數據共享
四.進程池
在利用Python進行系統管理的時候,特別是同時操作多個文件目錄,或者遠程控制多臺主機,並行操作可以節約大量的時間。多進程是實現並發的手段之一,需要註意的問題是:
- 很明顯需要並發執行的任務通常要遠大於核數
- 一個操作系統不可能無限開啟進程,通常有幾個核就開幾個進程
- 進程開啟過多,效率反而會下降(開啟進程是需要占用系統資源的,而且開啟多余核數目的進程也無法做到並行)
那麽什麽是進程池呢? 進程池就是控制進程數目
創建進程池的類:如果指定numprocess為3,則進程池會從無到有創建三個進程,然後自始至終使用這三個進程去執行所有任務,不會開啟其他進程
import time from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor def task(arg): time.sleep(2) print(arg) if __name__ == ‘__main__‘: pool = ProcessPoolExecutor(5) for i in range(10): pool.submit(task,i)
五.初始爬蟲
1.安裝:
pip3 install requests
pip3 install beautifulsoup4
示例相關:
a.以上示例進程和線程哪個好?
線程好
b.requests 模塊模擬瀏覽器發送請求
本質 requests.get():
創建socket客戶端
連接 (阻塞)
發送請求
接收請求 (阻塞)
斷開連接
c.線程和進程池
進程相關