1. 程式人生 > >記一次 python多執行緒+Queue的坑逼之旅

記一次 python多執行緒+Queue的坑逼之旅

背景~

在爬蟲中,需要用到代理ip,本人寫了一個模組來獲取和過濾代理ip(用多執行緒過濾,),,,在主執行緒中判斷可用的代理ip少於一定值了,獲取新的可用ip,問題來了。。多次呼叫代理ip模組之後報錯:

can't start new thread                         !!!!!!!!!!!!!!!?????????????????????????

what the fuck!!!!神馬鬼,一次只開20個執行緒怎麼會建立不了新的執行緒,,在檢查之後發現開啟的執行緒功能完成之後雖然結束了,但是還佔用著資源,,(沒釋放,在死迴圈??),持續開啟新的執行緒使我的電腦到達所能開啟的最大執行緒了!!!!!!

於是寫了一個例子來測試一下結果,程式碼如下:

import threading , time
from queue import Queue

class BdSpider(threading.Thread):
    def __init__(self, waiting):
        super(BdSpider, self).__init__()
        self.waiting = waitingdef run(self):     flag = True 
        while flag:
            ipone = self.waiting.get()
            self.waiting.task_done()       if self.waiting.empty():         print("ppppppppppppppppppppppppppppp")           flag = False
def ipAction(): for i in range(10): aaa = [] wait_list = Queue() thread_num = 20 for keyip in range(2000): if keyip: wait_list.put(keyip)#往Queue新增 for ii in range(100): print(ii + i*100) thread = BdSpider(wait_list) thread.setDaemon(True)
#設定守護程序 thread.start() aaa.append(thread) wait_list.join() print("-------------------------------") print(threading.active_count())#列印當前執行緒數 ipAction() print("main ------") print(threading.active_count())

列印當前的執行緒數量確實是在持續增加,,一直到極限,,,,

剛開始一直在找怎麼把執行緒強制殺死,,,怎麼釋放執行緒佔得資源,,,,,在網上找了兩天(日樂購),,測試各種各樣的可能,,no!!!!!!!!!!!!

程式碼中重寫類中run方法判斷佇列為空只走了一次!!!!!!!!!!!!!!!!

??????????why

心中無數個草擬嗎奔騰而過~~

於是乎查詢與Queue有關的東西,功夫不負有心人,終於在python的官網找到了答案,官網原話和例子:

Queue.join

阻止直到佇列中的所有專案都被獲取並處理。

每當專案新增到佇列時,未完成任務的計數就會增加。每當消費者執行緒呼叫task_done()以指示該專案已被檢索並且其上的所有工作都已完成時,計數就會下降當未完成任務的數量降至零時,join()取消阻止。如何等待排隊任務完成的示例:

def worker():
    while True:
        item = q.get()
        if item is None:
            break
        do_work(item)
        q.task_done()

q = queue.Queue()
threads = []
for i in range(num_worker_threads):
    t = threading.Thread(target=worker)
    t.start()
    threads.append(t)

for item in source():
    q.put(item)

# block until all tasks are done
q.join()

# stop workers
for i in range(num_worker_threads):
    q.put(None)
for t in threads:
    t.join()

,,,,照著更改之後,解決問題,,列印執行緒數量為1(主執行緒),,,,

有一個疑問?:為什麼開啟的100個執行緒只有1個判斷為空,子執行緒結束,剩餘的99個執行緒為什麼不判斷,不跳出!!!!!!(有大佬懂得請不吝賜教)

總結:

以我的理解,100個執行緒中只有一個執行緒判斷為空,出來了,join結束,不知道剩餘的99個執行緒沒判斷為空,,不知道死在裡邊哪裡了。官網例子是在佇列重新put進100個None,給100個執行緒判斷跳出,,然後就都出來了(執行緒全部結束)

print(threading.active_count()) 列印一下執行緒數量,,只剩下主執行緒, over~