Python 爬蟲 (四) --多執行緒

發表於2017-08-27

1. thread模組


  • python是支援多執行緒的, 主要是通過thread和threading這兩個模組來實現的。
  • python的thread模組是比較底層的模組(或者說輕量級),python的threading模組是對thread做了一些包裝的,可以更加方便的被使用。

簡要的看一下thread模組中含函式和常量

鎖物件的方法

1.1. thread多執行緒

2. threading模組

python的threading模組是對thread做了一些包裝的,可以更加方便的被使用。經常和Queue結合使用,Queue模組中提供了同步的、執行緒安全的佇列類,包括FIFO(先入先出)佇列QueueLIFO(後入先出)佇列LifoQueue,和優先順序佇列PriorityQueue。這些佇列都實現了鎖原語,能夠在多執行緒中直接使用。可以使用佇列來實現執行緒間的同步

2.1. 常用函式和物件

2.1.1. Thread物件

一般來說,使用執行緒有兩種模式, 一種是建立執行緒要執行的函式, 把這個函式傳遞進Thread物件裡,讓它來執行. 另一種是直接從Thread繼承,建立一個新的class,把執行緒執行的程式碼放到這個新的class裡。

常用兩種方式執行執行緒(執行緒中包含name屬性) :

  • 在建構函式中傳入用於執行緒執行的函式(這種方式更加靈活)
  • 在子類中重寫threading.Thread基類中run()方法(只重寫__init__()和run()方法)

建立執行緒物件後, 通過呼叫start()函式執行執行緒, 然後會自動呼叫run()方法.

 通過設定`daemon`屬性, 可以將執行緒設定為守護執行緒

範例:

2.2. 常用多執行緒寫法

  • 固定執行緒執行的函式

  • 外部傳入執行緒執行的函式

2.3. 生產者消費者問題

試著用python寫了一個生產者消費者問題(偽生產者消費者), 只是使用簡單的鎖, 感覺有點不太對, 下面另一個程式會寫出正確的生產者消費者問題

殺死多執行緒程式方法: 使用control + z掛起程式(程式依然在後臺, 可以使用ps aux檢視), 獲得程式的程式號, 然後使用kill -9 程式號殺死程式

參考一篇帖子解決了上述問題,重寫了生產者消費者問題程式, 參考連結慣例放在最後.

使用了wait()和notify()解決

當然最簡答的方法是直接使用Queue,Queue封裝了Condition的行為, 如wait(), notify(), acquire(), 沒看文件就這樣, 使用了Queue竟然不知道封裝了這些函式, 繼續滾去看文件了

2.4.簡單鎖

如果只是簡單的加鎖解鎖可以直接使用threading.Lock()生成鎖物件, 然後使用acquire()和release()方法

例如:

2.5. Condition

如果是向生產者消費者類似的情形, 使用Condition類 或者直接使用Queue模組

Condition

條件變數中有acquire()和release方法用來呼叫鎖的方法, 有wait(), notify(), notifyAll()方法, 後面是三個方法必須在獲取鎖的情況下呼叫, 否則產生RuntimeError錯誤.

  • 當一個執行緒獲得鎖後, 發現沒有期望的資源或者狀態, 就會呼叫wait()阻塞, 並釋放已經獲得鎖, 知道期望的資源或者狀態發生改變
  • 當一個執行緒獲得鎖, 改變了資源或者狀態, 就會呼叫notify()和notifyAll()去通知其他執行緒,

參考程式可以檢視上面的生產者消費者程式

3. 參考連結


相關文章