如何组合多处理和eventlet

时间:2018-01-12 01:41:33

标签: python multiprocessing eventlet

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

import multiprocessing
import eventlet

def subworker(num1, num2):
    print 'Start subworker %d,%d\n' % (num1, num2)
    eventlet.sleep(10)
    print 'End subworker %d,%d\n' % (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

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

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

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

如果名称 ==' 主要':     main()的