【问题标题】:Python Thread Communication SolutionPython线程通信解决方案
【发布时间】:2013-01-21 15:20:20
【问题描述】:

我正在编写一个非常基本的用 Python 编写的多线程网络爬虫,并为爬取页面和提取 url 的函数使用 While 循环,如下所示:

def crawl():
    while True:
        try:
            p = Page(pool.get(True, 10))
        except Queue.Empty:
            continue

        # then extract urls from a page and put new urls into the queue

(完整的源代码在另一个问题中:Multi-threaded Python Web Crawler Got Stuck

现在理想情况下,我想在 While 循环中添加一个条件,以使 while 循环在以下情况下退出:

  1. 池(存储 url 的 Queue 对象)为空,并且;

  2. 所有线程都处于阻塞状态,等待从队列中获取 url(这意味着没有线程将新 url 放入池中,因此让它们等待没有意义,并且会使我的程序卡住。)

例如:

#thread-1.attr == 1 means the thread-1 is blocking. 0 means not blocking

while not (pool.empty() and (thread-1.attr == 1 and thread-2.attr == 1 and ...)):
    #do the crawl stuff

所以我想知道是否有一个线程可以检查其他活动线程正在做什么,或者其他活动线程的状态或属性值。

已经阅读了threading.Event()的官方文档,但还是没搞明白。

希望有人能指点我的路:)

非常感谢!

马库斯

【问题讨论】:

    标签: python python-2.7 python-multithreading


    【解决方案1】:

    你可以尝试从头开始实现你想要的,我现在想到了不同的解决方案:

    • 使用threading.enumerate() 来检查是否有线程还活着。
    • 尝试实现一个线程池,让你知道哪个线程还活着,哪些返回到池中,这也有限制爬取第三方网站的线程数的好处(例如检查here) .

    如果你不想重新发明轮子,你可以使用现有的实现线程池的库,或者你也可以检查 gevent 使用绿色线程并提供thread pool,我已经实现了一些东西与此类似,使用类似:

    while 1:
        try:
            url = queue.get_nowait()
        except Empty:
            # Check that all threads are done.
            if pool.free_count() == pool.size:
                break
        ...
    

    您还可以在队列中写入一个标记对象,标记爬取完成并存在您的主循环并等待线程完成(例如使用池)。

    while 1:
        try:
            url = queue.get_nowait()
            # StopIteration mark that no url will be added to the queue anymore.
            if url is StopIteration:
                 break
        except Empty:
            continue
        ...
    pool.join()
    

    您可以选择自己喜欢的,希望对您有所帮助。

    【讨论】:

    • 非常感谢您提供如此全面的回答!我决定编写一个新字典来跟踪线程的状态。你的回答真的很有帮助
    • @BananaOnTheWall:很高兴它有帮助:)
    【解决方案2】:

    考虑查看此解决方案:Web crawler Using Twisted。正如该问题的答案所说,我还建议您查看http://scrapy.org/

    Python 中的多线程(直接使用线程)很讨厌,所以我会避免它并使用某种消息传递或基于反应器的编程。

    【讨论】:

      猜你喜欢
      • 2014-01-03
      • 2021-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-07
      • 1970-01-01
      • 1970-01-01
      • 2013-09-12
      相关资源
      最近更新 更多