記一次 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~



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM