python 多处理僵尸进程

python multi-processing zombie processes

我有一个python的多处理模块的简单实现

if __name__ == '__main__':
jobs = []

while True:
    for i in range(40):
        # fetch one by one from redis queue
        #item = item from redis queue
        p = Process(name='worker '+str(i), target=worker, args=(item,))

        # if p is not running, start p
        if not p.is_alive():
            jobs.append(p)
            p.start()

    for j in jobs:
        j.join()
        jobs.remove(j)


def worker(url_data):
    """worker function"""
    print url_data['link']

我希望这段代码做什么:

  1. 运行死循环,一直等待Redis队列
  2. 如果 Redis 队列不为空,则获取项目。
  3. 创建 40 个 multiprocess.Process,不多不少
  4. 如果一个进程已完成处理,则启动新进程,这样 ~40 个进程一直 运行正在运行。

我读到,为了避免应该绑定(加入)父进程的僵尸进程,这是我希望在第二个循环中实现的。但问题是,在启动时它会产生 40 个进程,workers 完成处理并进入僵尸状态,直到所有当前产生的进程都没有完成, 然后在 "while True" 的下一次迭代中,相同的模式继续。

所以我的问题是: 我怎样才能避免僵尸进程。并在 40 个中有 1 个完成后立即生成新进程

对于您所描述的任务,通常最好使用不同的方法 Pool

您可以让主进程获取数据,让工作进程处理它。

Python Docs

中的 Pool 为例
def f(x):
    return x*x

if __name__ == '__main__':
    pool = Pool(processes=4)              # start 4 worker processes
    result = pool.apply_async(f, [10])    # evaluate "f(10)" asynchronously
    print result.get(timeout=1)           # prints "100" unless your computer is *very* slow
    print pool.map(f, range(10))          # prints "[0, 1, 4,..., 81]"

我还建议使用 imap 而不是 map 因为看起来你的任务可以是异步的。

您的代码大致如下:

p = Pool(40)

while True:
  items = items from redis queue
  p.imap_unordered(worker, items) #unordered version is faster


def worker(url_data):
  """worker function"""
  print url_data['link']