1. 程式人生 > >python 程序 執行緒 協程

python 程序 執行緒 協程

  併發與並行:並行是指兩個或者多個事件在同一時刻發生;而併發是指兩個或多個事件在同一時間間隔內發生。在單核CPU下的多執行緒其實都只是併發,不是並行。

 

  程序是系統資源分配的最小單位,程序的出現是為了更好的利用CPU資源使到併發成為可能。程序由作業系統排程。

  執行緒的出現是為了降低上下文切換的消耗,提高系統的併發性,並突破一個程序只能幹一樣事的缺陷,使到程序內併發成為可能。執行緒共享程序的大部分資源,並參與CPU的排程, 當然執行緒自己也是擁有自己的資源的,例如,棧,暫存器等等。執行緒由作業系統排程。

  協程通過線上程中實現排程,避免了陷入核心級別的上下文切換造成的效能損失,進而突破了執行緒在IO上的效能瓶頸。協程由程式碼排程。

 

  多個執行緒相對獨立,有自己的上下文,切換受系統控制;而協程也相對獨立,有自己的上下文,但是其切換由自己控制,由當前協程切換到其他協程由當前協程來控制。

 

  執行緒,在計算機裡面通常的分類是核心級執行緒和使用者級執行緒。核心級執行緒的排程是由系統完成的,而使用者級執行緒的排程是由使用者來控制的。那麼Python標準庫提供的執行緒是那一類呢?如果我們瞭解或者使用過gevent和eventlet,進行下對比,我們就很容易回答出來了。Python提供的執行緒是核心級的,而gevent和eventlet提供的則是使用者級的執行緒。這類使用者級的執行緒,我們叫它協程,也可以叫green thread。

 

  GIL鎖是對於直譯器的,它保證一個程序同一時刻只存在一個直譯器例項,並不是說Python 不能利用多核,而是不能“有效”利用多核。一個程序的多個執行緒執行在多核上的時候,直譯器仍有可能被某一執行緒阻塞導致其它執行緒的程式碼無法執行。移除GIL鎖是沒有必要的,會給多執行緒程式設計造成巨大的心智負擔。要想充分利用多核,可以使用多程序+協程的方式,多程序下不存在GIL鎖的問題,而協程的系統開銷遠比執行緒小所以理論上來說效能更優,協程可以輕鬆的達到十萬甚至百萬併發的級別,而子執行緒到達這個量級的時候排程開銷會比較大。從Python3加入的新特性asyncio可以知道,python官方也認為與其解決GIL鎖對多執行緒程式設計造成的困擾,不如轉而鼓勵使用語言級別的協程。雖然具體實現上有差別,然而Golang,Javascript也是採用類似的方式解決非同步的問題的。

 

    uwsgi可以配置引數啟動多個程序,還可以配置一個程序有多個執行緒。eventlet則是開啟多個協程。      程序間通訊的方法有:訊息佇列(redis、mongoDB等)、管道、共享記憶體、訊號