注意標題裡面有三個keyword,遞迴 執行緒池 佇列
這是我在開發爬蟲程式時候碰到的需求,我們知道爬網頁一般都使用廣度優先搜尋,每個頁面下面都可能有下層頁面。為了加快爬行速度,我們很容易想到用多執行緒來實現。
但是多執行緒必須受控,不能無限的建立執行緒,這樣機器受不了,伺服器也受不了。所以多執行緒必須滿足下面條件:
執行緒數限制,超過限制則加入到佇列中等待。同時,執行緒中允許建立新的執行緒,我稱之為遞迴執行緒。
下面是實現**
using system;
using system.collections.concurrent;
using system.threading;
using system.threading.tasks;
namespace mediaspider );
}queue = new concurrentqueue();
}public void add(action action)
public void wait()
canceltokensource = new cancellationtokensource();
trycatch (operationcanceledexception)
// 如果都執行完畢,則退出等待
return;}}
}}
呼叫方法
pool = new taskqueue(6);//初始化執行緒池,大小為6
pool.add(() => );//新增任務
pool.add(() => );//新增任務
pool.add(() => );//新增任務
pool.wait();//等待任務執行完畢
實現的思路如下:
主線程只是守護執行緒,任務都在其他執行緒裡面實現。
守護執行緒(wait)實現下面的功能
1.執行緒排程:當執行緒池有空閒的時候,把佇列中的執行緒加入執行緒池執行
2.等待全部執行緒池和佇列執行完畢
實現中遇到的問題
必須等待執行緒池和佇列同時為空才能算執行完畢,執行緒也會不停的建立新的執行緒。
如果沒有遞迴就比較好辦,有了遞迴,佇列都執行完了,執行緒池中的執行緒還可以新增佇列。不能夠單純的waitall。想了幾個方式,都有些問題。後來發現waitall(task, cancellationtoken)是可以被打斷的,才最終解決這個問題。
如果不需要遞迴,那麼用普通的waitall就可以了,**還可以簡化。
任務佇列剛開始是用queue來實現的,由於不是執行緒安全需要lock來互斥,後來發現執行緒安全的concurrentqueue,就把lock去掉,提高了效能
執行緒佇列,執行緒池,協程
執行緒的queue,類似於程序 作用也是類似,queue n 規範放入值的數量 這個和之前一樣是為了實現先進先出 import queue q queue.queue 2 括號內可加入數字規範放入值的數量,不加則不會規範 q.put 123 q.put qweqwe q.put 111 print ...
執行緒佇列 執行緒池 協程
1 執行緒佇列 from multiprocessing queue joinablequeue 程序ipc佇列 from queue import queue 執行緒佇列 先進先出 from queue import lifoqueue 後進先出的 方法都是一樣的 put get put nowa...
Python 執行緒池 佇列任務
現在又佇列長度為n的乙個任務佇列需要處理,同時處理的任務數目為m,如何處理 python3中threading.thread 執行緒,通過start 方法來啟動,較為簡單的方法就是開始m個任務,m個任務都結束,再執行下一批m個任務,這裡就用到了 futures 其中又executor.submit ...