[英]Too many threads in python threading - Recursive traversal
我有一個腳本來遍歷一個AWS S3存儲桶以在文件級別進行一些聚合。
from threading import Semaphore, Thread
class Spider:
def __init__(self):
self.sem = Semaphore(120)
self.threads = list()
def crawl(self, root_url):
self.recursive_harvest_subroutine(root_url)
for thread in self.threads:
thread.join()
def recursive_harvest_subroutine(self, url):
children = get_direct_subdirs(url)
self.sem.acquire()
if len(children) == 0:
queue_url_to_do_something_later(url) # Done
else:
for child_url in children:
try:
thread = Thread(target=self.recursive_harvest_subroutine, args=(url,))
self.threads.append(thread)
thread.start()
self.sem.release()
過去一直運行良好,直到遇到一堆包含數十萬個子目錄的幾TB數據。 self.threads中Thread對象的數量增加非常快,服務器很快向我報告了
RuntimeError: can't start new thread
我需要在腳本中做一些額外的處理,所以我不能只從存儲桶中獲取所有文件。
目前,在腳本可以並行化之前,我將深度至少設置為2,但這只是一種解決方法。 任何建議表示贊賞。
因此,原始代碼的工作方式是BFS,BFS在隊列中創建了許多等待線程。 我將其更改為DFS,一切正常。 偽代碼,以防將來有人需要:
def __init__(self):
self.sem = Semaphore(120)
self.urls = list()
self.mutex = Lock()
def crawl(self, root_url):
self.recursive_harvest_subroutine(root_url)
while not is_done():
self.sem.acquire()
url = self.urls.pop(0)
thread = Thread(target=self.recursive_harvest_subroutine, args=(url,))
thread.start()
self.sem.release()
def recursive_harvest_subroutine(self, url):
children = get_direct_subdirs(url)
if len(children) == 0:
queue_url_to_do_something_later(url) # Done
else:
self.mutex.acquire()
for child_url in children:
self.urls.insert(0, child_url)
self.mutex.release()
沒有join()
所以我實現了自己的is_done()
檢查。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.