再次执行失败的线程

时间:2014-06-17 20:40:30

标签: python multithreading python-2.7

所以我的脚本使用了大约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循环结束后,线程没有完成,所以列表不为空。 我想要做的是捕获失败的那些,因为系统耗尽内存并再次执行它们(如果需要的话,再次执行)。

非常感谢你!

1 个答案:

答案 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中删除该项,导致管理器将其重新排队到另一个线程上。