多处理+ psycopg2僵尸儿童

时间:2011-04-26 17:49:25

标签: python multiprocessing psycopg2 zombie-process

我正在尝试使用psycopg和多处理插入和更新几百万行。按照http://initd.org/psycopg/docs/usage.html#thread-and-process-safety中的文档,每个孩子都有自己与DB的连接。

但在执行过程中,只有一个孩子跑,而其他孩子成为僵尸。这个脚本本身很简单,这里有一个修剪过的版本,

import os
import psycopg2

from multiprocessing import Process


def _target(args):
    # Each forked process will have its own connection
    # http://initd.org/psycopg/docs/usage.html#thread-and-process-safety
    conn = get_db_connection()

    # Stuff seems to execute till this point in all the children
    print os.getpid(), os.getppid()

    # Do some updates here. After this only one child is active and running
    # Others become Zombies after a while.


if __name__ == '__main__':
    args = "Foo"
    for i in xrange(3):
        p = Process(target=_target, args=(args,))
        p.start()

我还通过窥视pg_locks来检查表是否有升级锁,但看起来并非如此。我错过了一些明显的东西吗?

1 个答案:

答案 0 :(得分:0)

您的流程变成了僵尸,因为工作已完成,但流程未加入。 我通过这个单一测试重现了你的问题(我添加了睡眠以模拟长期工作):

import os
import time
from multiprocessing import Process

def _target(args):
    print os.getpid(), os.getppid()
    time.sleep(2)
    print os.getpid(), "will stop"

if __name__ == '__main__':
    args = "Foo"
    for i in xrange(3):
        p = Process(target=_target, args=(args,))
        p.start()
    import time
    time.sleep(10)

执行此操作时,在3个进程打印后它们将停止,它们将进入ps视图(它们不再移动,但实际上并没有死,因为父亲仍然持有它们)。

如果我用这个替换主要部分,我没有更多的僵尸:

if __name__ == '__main__':
    args = "Foo"
    processes = []
    for i in xrange(3):
        p = Process(target=_target, args=(args,))
        processes.append(p)
        p.start()
    for p in processes:
        p.join()
    import time
    time.sleep(10)