所以我的脚本使用了大约50k个线程,但一次只运行10个。我使用线程库和BoundedSemaphore一次将线程限制为10。在某些情况下,所有线程都没有足够的内存,但重要的是所有线程都得到处理,所以我想重复因内存不足而被杀死的线程。
import some_other_script, threading
class myThread (threading.Thread):
def __init__(self, item):
threading.Thread.__init__(self)
self.item = item
def run(self):
threadLimiter.acquire()
some_other_script.method(self.item)
somelist.remove(self.item)
threadLimiter.release()
threadLimiter = threading.BoundedSemaphore(10)
somelist = ['50,000 Items','.....]
for item in somelist:
myThread(item).start()
正如您所看到的那样,到目前为止我唯一能想到的想法是在somelist.remove(self.item)
的每个帖子中删除从列表中处理的项目。 (每个项目都是唯一的,只在列表中出现一次)。
我的想法是我可以围绕for循环运行一个while循环,检查它是否仍然包含无效的项,因为在for循环结束后,线程没有完成,所以列表不为空。
我想要做的是捕获失败的那些,因为系统耗尽内存并再次执行它们(如果需要的话,再次执行)。
非常感谢你!
答案 0 :(得分:1)
这解决了太多活动线程问题和问题中的问题:
def get_items():
threads = threading.enumerate()
items = set()
for thr in threads:
if isinstance(thr, myThread): items.add(thr.item)
return items
def manageThreads(howmany):
while bigset:
items = get_items()
items_to_add = bigset.difference(items)
while len(items) < howmany:
item = items_to_add.pop()
processor = myThread(item)
processor.start()
with thread_done:
thread_done.wait()
thread_done = threading.Condition()
bigset = set(["50,000 items", "..."])
manageThreads(10)
mythread类的运行方法:
def run(self):
try:
some_other_script.method(self.item)
bigset.remove(self.item)
finally:
with thread_done:
thread_done.notify()
Threading.enumerate()
返回当前活动线程对象的列表。因此,manageThreads函数最初创建10个线程,然后等待一个完成,然后再次检查线程计数,依此类推。如果线程耗尽内存或在处理过程中发生其他错误,它将不会从bigset
中删除该项,导致管理器将其重新排队到另一个线程上。