我该如何修复这个多线程Python脚本?

时间:2010-06-26 00:19:12

标签: python multithreading

我正在编写一个python脚本来读取域列表,找出Mcafee的Siteadvisor服务给出的评级,然后将域和结果输出到CSV。

我的脚本是this previous answer。它使用urllib来搜索相关域的Siteadvisor页面(不是最好的方法,我知道,但Siteadvisor没有其他选择)。不幸的是,它没有产生任何东西 - 我一直都会遇到这个错误:

Traceback (most recent call last):
  File "multi.py", line 55, in <module>
    main()
  File "multi.py", line 44, in main
    resolver_thread.start()
  File "/usr/lib/python2.6/threading.py", line 474, in start
    _start_new_thread(self.__bootstrap, ())
thread.error: can't start new thread

这是我的剧本:

import threading
import urllib

class Resolver(threading.Thread):
    def __init__(self, address, result_dict):
        threading.Thread.__init__(self)
        self.address = address
        self.result_dict = result_dict

    def run(self):
        try:
            content = urllib.urlopen("http://www.siteadvisor.com/sites/" + self.address).read(12000)
            search1 = content.find("didn't find any significant problems.")
            search2 = content.find('yellow')
            search3 = content.find('web reputation analysis found potential security')
            search4 = content.find("don't have the results yet.")

            if search1 != -1:
                result = "safe"
            elif search2 != -1:
                result = "caution"
            elif search3 != -1:
                result = "warning"
            elif search4 != -1:
                result = "unknown"
            else:
                result = ""

            self.result_dict[self.address] = result

        except:
            pass


def main():
    infile = open("domainslist", "r")
    intext = infile.readlines()
    threads = []
    results = {}
    for address in [address.strip() for address in intext if address.strip()]:
        resolver_thread = Resolver(address, results)
        threads.append(resolver_thread)
        resolver_thread.start()

    for thread in threads:
        thread.join()

    outfile = open('final.csv', 'w')
    outfile.write("\n".join("%s,%s" % (address, ip) for address, ip in results.iteritems()))
    outfile.close()

if __name__ == '__main__':
    main()

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

看起来你正试图开始太多线程。

您可以查看[address.strip() for address in intext if address.strip()]列表中的项目数。我认为这是一个问题。基本上,可用资源的限制允许启动新线程。

对此的解决方案是将列表分块为20个元素,执行操作(在20个线程中),等待线程完成其工作,然后选择下一个块。执行此操作直到处理列表中的所有元素。

您还可以使用一些线程池来更好地管理线程。 (我最近使用过this implementation)。

答案 1 :(得分:1)

您可以创建的线程数可能有一个上限,而且您可能已超过它。

建议:创建一个固定数量的小型解析器 - 低于10可能会获得90%的可能并行优势 - 以及来自python队列lib的(线程安全)队列。让主线程将所有域转储到队列中,让每个Resolver一次从队列中获取一个域并对其进行处理。