如何组合多处理和eventlet

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何组合多处理和eventlet相关的知识,希望对你有一定的参考价值。

我有一个任务需要启动2个进程,并且在每个进程内需要启动2个线程才能真正起作用。下面是我用来模拟用例的源代码。

import multiprocessing
import eventlet

def subworker(num1, num2):
    print 'Start subworker %d,%d
' % (num1, num2)
    eventlet.sleep(10)
    print 'End subworker %d,%d
' % (num1, num2)

def worker(**kwargs):
    number = kwargs['number']
    pool = eventlet.GreenPool(size=2)
    pool.spawn_n(subworker, number, 1)
    pool.spawn_n(subworker, number, 2)
    pool.waitall()

def launcher(number):
    kwargs = {'number': number}
    th = multiprocessing.Process(target=worker, kwargs=kwargs)
    th.start()
    while True:
        if not th.is_alive():
            break
        eventlet.sleep(0)

    th.join()


def main():
    pool = eventlet.GreenPool(size=2)
    pool.spawn_n(launcher, 1)
    pool.spawn_n(launcher, 2)
    pool.waitall()

main()

当我运行这个python脚本时,我的预期输出是这样的:

Start subworker 1,1 
Start subworker 1,2
Start subworker 2,1
Start subworker 2,2
End subworker 1,1
End subworker 1,2
End subworker 2,1
End subworker 2,2

但我真正得到的是:

Start subworker 1,1
Traceback (most recent call last):

  File "/Users/leehom/python_local/lib/python2.7/site-packages/eventlet/greenpool.py", line 82, in _spawn_n_impl
Start subworker 1,2
    func(*args, **kwargs)

  File "/Users/leehom/Desktop/home/work_dir/source/snips/Test_multiprocessing_and_eventlet.py", line 27, in launcher
Start subworker 2,1
    if not th.is_alive():

  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/process.py", line 155, in is_alive
Start subworker 2,2
    assert self._parent_pid == os.getpid(), 'can only test a child process'

AssertionError: can only test a child process
Start subworker 1,1
Start subworker 1,2
Start subworker 2,1
Start subworker 2,2
End subworker 1,1
End subworker 1,2
End subworker 2,1
End subworker 2,2
End subworker 1,1
End subworker 1,2
End subworker 2,1
End subworker 2,2
Process finished with exit code 0

似乎发射器被叫了两次。我不明白为什么会这样。

如果我在主函数中注释一行

def main():
    pool = eventlet.GreenPool(size=2)
    pool.spawn_n(launcher, 1)
    # pool.spawn_n(launcher, 2)
    pool.waitall()

结果是对的:

Start subworker 1,1
Start subworker 1,2
End subworker 1,1
End subworker 1,2

任何人都知道如何解决这个问题以及为什么会出现此问题?

答案

截至2018-01,Eventlet和多处理不能很好地协同工作。您最好的选择是在外部生成工作进程。第二个最佳选择是os.fork()创建工作进程,然后才是import eventlet

订阅此问题以在解决多处理兼容性时收到通知。 https://github.com/eventlet/eventlet/issues/147

另一答案

主模块应该是可导入的,以便多个进程正常工作。不要在全局空间中调用main(),使用它:

如果name =='main':main()

以上是关于如何组合多处理和eventlet的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 多处理进程中运行较慢的 OpenCV 代码片段

flask-SocketIO 和 eventlet 有问题

如何在多片段活动中处理 onContextItemSelected?

openstack中eventlet使用

48个值得掌握的JavaScript代码片段(上)

如何组合绑定片段而不将它们包装在 XML 文字中