【问题标题】:Python gevent pool.join() waiting foreverPython gevent pool.join() 永远等待
【发布时间】:2014-05-19 13:50:13
【问题描述】:

我有这样的功能

def check_urls(res):
    pool = Pool(10)
    print pool.free_count()
    for row in res:
        pool.spawn(fetch, row[0], row[1])
    pool.join()

pool.free_count() 输出值 10。

我使用pdb 进行追踪。程序在 pool.spawn() 循环之前运行良好。

但它永远在pool.join() 线上等待。

谁能告诉我怎么了?

【问题讨论】:

    标签: python multithreading gevent greenlets


    【解决方案1】:

    但它永远在 pool.join() 行等待。
    谁能告诉我怎么了?

    没什么!

    虽然,我首先写了行下面的内容,但 gevent 中的 join() 函数的行为方式与子进程/线程中的行为方式几乎相同。在所有的greenlets完成之前它会阻塞。

    如果您只想测试池中的所有greenlet 是否都结束了,您可能需要检查池中每个greenlet 上的ready()

    is_over = all(gl.ready() for gl in pool.greenlets)
    

    基本上,.join() 不会一直等待,它会一直等到您的线程结束。如果您的线程之一永远不会结束,那么join() 将永远阻塞。因此,请确保每个greenlet 线程都终止,并且join() 将在所有作业完成后重新执行。


    edit:以下内容仅适用于子进程或线程模块标准 API。 GEvent 的 greenlet 池与“标准”API 不匹配。

    线程/进程上的join() 方法旨在使主进程/线程永远等待,直到子进程/线程结束。

    您可以使用timeout 参数让它在一段时间后恢复执行,或者您可以使用is_alive() 方法检查它是否正在运行而不阻塞。

    在进程/线程池的上下文中,join() 也需要在调用close()terminate() 之后触发,所以您可能想要:

    for row in res:
        pool.spawn(fetch, row[0], row[1])
    pool.close()
    pool.join()
    

    【讨论】:

    • 我在这里没有看到is_alive 方法。 github.com/surfly/gevent/blob/master/gevent/pool.py
    • 哦,我错过了你的 gevent 标签 /o\ 我的错,我说的是标准进程或线程池。
    • 无论如何,is_alive 等效方法将在每个 greenlet 进程上,而不是在池本身上。
    • 我也收到此错误AttributeError: 'Pool' object has no attribute 'close'
    • 我还是没有得到你的答案。我是否必须使用is_over 而不是pool.join()
    猜你喜欢
    • 1970-01-01
    • 2013-11-24
    • 2012-02-24
    • 1970-01-01
    • 2019-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-13
    相关资源
    最近更新 更多