Python編程——線程和進程

IO密集型和CPU密集型

我們會針對不同的任務類型來決定是否使用python的多線程。

IO密集型

一般是指磁盤讀寫,例如讀取和寫入文件等等,和網絡應用,典型的有網絡爬蟲等。因爲這些操作限制你的並不是程序的性能,而是硬盤讀寫的速度或者網絡的速度。

CPU密集型

主要就是指計算任務。此時需要發揮的就是程序本身的性能了,和其他的速度關係不大。

線程和進程

線程

所有的線程都在一個進程中,他們會自己記錄自己在一個任務中運行到了說明地方,以便重新調用的時候繼續運行。各個線程之間共享同一份數據,也能更方便地通訊和同步。但是要注意避免由於訪問數據順序不同而導致數據結果不同步的現象。

同步機制

python包含了多種線程間數據同步的機制。其中最常用就是隊列Queue

隊列模式

其核心思想就是排隊。利用Queue模塊將需要處理的任務步驟加入隊列中,基本按照先來後到的方式進行處理,當然也可以設置優先級。

線程池

因爲線程的創建和銷燬都是需要耗費資源的,在執行任務的過程中不斷地創建和銷燬線程是很浪費的一件事情。那麼我們可以利用池的概念,先創建一些線程把他們放到線程池中,需要用的時候就拿出來用,不需要用的時候就放回去而不是銷燬掉。通過這樣的方式來節省資源。

進程

一個進程就是一次程序的執行,每個進程都有自己獨立的內存,地址和其他數據。進程可以由操作系統控制運行。在進行CPU密集型任務的時候,由於python有GIL的限制,不能使用多線程,卻可以使用多進程來並行計算。

GIL

全局解釋鎖(Global Interpreter Lock),是Cpython特有的爲了保護線程之間數據的完整性和同步性而特別設置的。有了這個鎖以後,多線程的CPU通通變成了單線程的了。

但是,如果我們的目標是要進行IO密集型的任務的時候,由於其他速度和性能的限制,比如讀寫進度,網絡響應等等,那麼此時python的多線程就會在等待的時間被充分利用了。如果是CPU密集型的任務,由於GIL的關係,首先多線程的效率理論上和單線程一樣,但是線程之間的通信也會有消耗,其結果就是多線程反而不如單線程了。

Python的併發

1.使用threading庫在單獨的線程中執行任意python可調用對象

from threading import Thread
t = Thread(target=func,args=(params,))
# 開始線程
t.start()
# 連接線程
t.join()

2.使用Queue模塊來實現線程之間的通信

from queue import Queue
# 加入隊列
Queuq.put()

3.線程池

from concurrent.futures import ThreadPoolExecutor

4.進程池

from concurrent.futures import ProcessPoolExecutor
with ProcessPoolExecutor() as pool:
    do work in parallel using pool
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章