進程的引入:爲了提升計算機系統的效率和加強計算機系統內各類硬件的並行操做能力,操做系統要求程序結構適應併發處理的須要,即時計算機系統中能同時存在兩個以上的正在執行的的程序,順序的程序的結構並不具有併發處理的能力,所以爲了描述操做系統的併發性,就引入了進程這個概念。
進程是一個能獨立運行的單位,能與其餘程序並行的活動。從結構上說,每一個進程都由一個程序段(數據)和一個進程控制塊PCB組成。
單CPU狀況下,多個進程會經過時間片輪轉的方式輪流去佔用CPU,實現併發,要實現並行的話得須要多CPU。
多進程輪流佔用CPU時,須要作進程切換,進程1切換到進程2運行時,系統須要保留進程1運行時的所需的信息。python
python 進程是經過multiprossing這個庫來建立的。
1.啓動方式有三種:
spawn :父進程啓動一個新的Python解釋器進程。子進程只會繼承那些運行進程對象的 run() 方法所需的資源。特別是父進程中非必須的文件描述符和句柄不會被繼承。相對於使用 fork 或者 forkserver,使用這個方法啓動進程至關慢。
fork:父進程使用 os.fork() 來產生 Python 解釋器分叉。子進程在開始時實際上與父進程相同。父進程的全部資源都由子進程繼承。請注意,安全分叉多線程進程是棘手的。安全
只存在於Unix。Unix中的默認值。
forkserver:程序啓動並選擇 forkserver 啓動方法時,將啓動服務器進程。從那時起,每當須要一個新進程時,父進程就會鏈接到服務器並請求它分叉一個新進程。分叉服務器進程是單線程的,所以使用 os.fork() 是安全的。沒有沒必要要的資源被繼承。
可在Unix平臺上使用,支持經過Unix管道傳遞文件描述符。服務器
2.multiprossing支持的進程之間的通訊方式有兩種
隊列:
使用Queue類,是一個相似queue.Queue的克隆多線程
from multiprocessing import Process,Queue def func(q): q.put(["python","Process"]) if __name__ == '__main__': q = Queue() p = Process(func,args=(q,) p.start() print(q.get()) # prints '["python","Process"]' p.join()
隊列是線程和進程安全的
管道:
Pipe()函數返回一個由管道鏈接的鏈接對象,默認狀況下是雙工的併發
from multiprocessing import Process,Pipe def func(conn): conn.send(["python","Process"]) conn.close() if __name__ == '__main__': parent_conn,child_conn = Pipe() p = Process(func,args=(child_conn,) p.start() print(parent_conn.recv()) # prints '["python","Process"]' p.join()
返回的兩個鏈接對象Pipe()表示管道的兩端。每一個鏈接對象都有send()和revc()方法。請注意:若是兩個進程或者線程同時嘗試寫入或讀取管道同一端,則管道中的數據可能會損壞。固然若是是不一樣的進程同時使用管道的不一樣端的狀況下不存在損壞的風險。函數
孤兒進程:多進程環境下,父進程先退出,而它的子進程還在運行,那麼那些子進程將成爲孤兒進程。孤兒進程將被init進程(進程號爲1)所回收。
殭屍進程:一個進程使用fork建立子進程,若是子進程退出,而父進程沒有調用wait或waitpid獲取子進程的狀態信息,那麼子進程的進程描述符仍然保存在系統中
清除殭屍進程的方式:
1.結束父進程,父進程結束子進程也就結束了,可是這個比較暴力,由於咱們仍是須要父進程繼續運行的
2.經過wait調用來讀取子進程退出狀態。好比經過multiprocess.Process產生的進程能夠經過子進程的join()方法來wait,也能夠父進程中處理SIGCHLE信號,在處理程序中調用wai系統調用或者直接設置爲SIG_IGN來清除殭屍進程。
3.就是把子進程變成孤兒進程spa
線程
線程的引入是由於多進程進行進程切換時開銷較大。
線程是比進程更小的能獨立運行的基本單位,試圖經過線程來提升系統內程序併發執行效率。
因爲進程是一個資源擁有者,所以在建立,撤銷,切換這些動做中,系統必須付出較大的時間和空間開銷。因此在系統中不宜設置過多的進程。這也就限制了併發程度的進一步提升。
人們就把進程做爲資源分配單位和調度單位這兩個屬性分開處理,即進程仍是做爲資源分配的基本單位,可是不做爲調度的基本單位(不多調度或者切換),把調度執行與切換的責任交給線程。這樣線程的概念就造成了。
線程是一個輕量級進程,是被系統獨立調度和分派的基本單位,線程本身不擁有系統資源,只擁有一點在運行中必不可少的資源,但它可與同屬一個進程的其餘線程共享進程所擁有的所有資源。操作系統
python中,經過threading庫來產生線程線程
from threading import Thread def func(): print("-----") if __name__ == '__main__': t = Thread(func) t.start()