參考連接:https://www.cnblogs.com/alex3714/articles/5230609.htmlhtml
https://www.cnblogs.com/work115/p/5620272.htmlpython
編程離不開併發,而併發的基礎就離不開線程、進程、協程。那麼什麼是線程、進程、協程呢?編程
進程:安全
進程是對資源進行分配和調度的最小單位,是操做系統結構的基礎,是線程的容器(就像是一幢房子,一個空殼子,並不能運動)。微信
線程的概念主要有兩點:多線程
一、進程是一個實體,每一個進程都有本身的地址空間,通常包括文本區域(text region)、數據區域(data region)和堆棧(stack region)併發
文本區域存儲處理器執行的代碼;數據區域存儲變量和進程在執行期間所使用的動態分配的內存;堆棧區域存儲在活動過程當中所調用的指令和本地變量異步
二、進程是一個「執行中的程序」。程序是一個沒有生命的實體,只有在操做系統調用時,他纔會成爲一個活動的實體:進程。函數
線程:spa
線程被稱爲輕量級進程,是操做系統可以運算調度的最小單位,線程被包含在進程中,是進程中實際處理單位(就像是房子裏的人,人才能動)
一個標準的線程由線程ID,當前指令指針(PC),寄存器集合和堆棧組 成。另外,線程是進程中的一個實體,是被系統獨立調度和分派的基本單位,
線程本身不擁有系統資源,只擁有一點兒在運行中必不可少的資源,但它可與同屬一個 進程的其它線程共享進程所擁有的所有資源。
一個線程能夠建立和撤消另外一個線程,同一進程中的多個線程之間能夠併發執行。因爲線程之間的相互制約,導致線程 在運行中呈現出間斷性。
線程也有就緒、阻塞和運行三種基本狀態。就緒狀態是指線程具有運行的全部條件,邏輯上能夠運行,在等待處理機;
運行狀態是指線程佔有處理機正在運行;阻塞狀態是指線程在等待一個事件(如某個信號量),邏輯上不可執行。
每個程序都至少有一個線程,若程序只有一個線程,那就是程序自己。
進程與線程的區別:
進程是資源分配的最小單位,線程是系統調度(程序執行)的最小單位。
進程有本身獨佔的地址空間,每啓動一個進程,系統就須要爲它分配地址空間;
而一個進程下全部線程共享該進程的全部資源,使用相同的地址空間,所以CPU在線程之間切換遠遠比在進城之間切換花費小,並且建立一個線程的開銷也遠遠比開闢一個進程小得多。
線程之間通訊更加方便,同一進程下全部線程共享全局變量、靜態變量等數據。而進程之間通訊須要藉助第三方。
線程只能歸屬於一個進程而且它只能訪問該進程所擁有的資源。當操做系統建立一個進程後,該進程會自動申請一個名爲主線程或首要線程的線程。
處理IO密集型任務或函數用線程;
處理計算密集型任務或函數用進程。
協程:
協程又叫微線程,一個程序能夠包含多個協程,就比如一個進程包含多個線程。協程的調度徹底由用戶控制。
協程擁有本身的寄存器上下文和棧。協程調度切換時,將寄存器上下文和棧保存到其餘地方,在切回來的時候,恢復先前保存的寄存器上下文和棧,
直接操做棧則基本沒有內核切換的開銷,能夠不加鎖的訪問全局變量,因此上下文的切換很是快。
協程和線程的阻塞是有本質區別的。協程的暫停徹底由程序控制,線程的阻塞狀態是由操做系統內核來進行切換。
所以,協程的開銷遠遠小於線程的開銷。
線程和協程的區別:
一個線程能夠多個協程,一個進程也能夠單獨擁有多個協程,這樣python中則能使用多核CPU。
線程進程都是同步機制,而協程則是異步
協程能保留上一次調用時的狀態,每次過程重入時,就至關於進入上一次調用的狀態
咱們常說python中的多線程都是假的,由於不管你啓多少個線程,你有多少個cpu, Python在執行的時候會淡定的在同一時刻只容許一個線程運行。
這又是爲何呢?其實這主要是因爲GIL的存在而形成的,那麼GIL又是什麼呢?
GIL:
GIL(Global Interpreter Lock) 全局解釋器鎖
官方解釋:In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once.
This lock is necessary mainly because CPython’s memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.
什麼意思呢?在CPython中,全局解釋器鎖是一個互斥鎖,它能夠防止多個本機線程同時執行Python字節碼。這個鎖是必要的,主要是由於CPython的內存管理不是線程安全的。簡而言之,GIL其實就是一個全局排它鎖,他規定了在同一時間僅僅只能有一個線程來對數據進行操做。
首先說一下,這個GIL並非python的缺陷,它僅僅在CPython中存在,這是由於在最初,python是由C寫的,在起線程時是直接調用的操做系統的系統線程。
因此GIL僅僅在Cpython的python解釋器中存在該問題,其餘的如JPython就沒有這個問題,可是大多數的python執行環境默認使用CPython解釋器,
因此GIL這個問題比較常見。
理清了進程、線程、協程和GIL的基本概念,下一篇博客咱們再來講說在Python中如何建立線程、進程、協程。
想了解更多Python關於爬蟲、數據分析的內容,歡迎你們關注個人微信公衆號:悟道Python