2011-04-26 103 views
2

我想插入并更新使用psycopg和multiprocessing几百万行。通过http://initd.org/psycopg/docs/usage.html#thread-and-process-safety中发现的文档,每个孩子都有自己的连接到数据库。multiprocessing + psycopg2僵尸儿童

但是在执行过程中,只有一个孩子在其他人变成僵尸时运行。在本身的脚本是非常简单,这里是相同的修剪版本,

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有逐步升级的锁,但它看起来像它的情况并非如此。我错过了明显的东西吗?

+0

是什么get_db_connection办?它是创建一个新的连接还是返回一个共享连接?根据你选择的文档,它应该创建一个新的连接。 – 2011-04-26 20:02:42

+0

Philip,不,它不使用共享连接。为每个分叉的子项创建一组新的连接和光标。 (应该是create_db_connection()) – sudharsh 2011-04-27 05:00:57

回答

0

您的进程变成僵尸,因为作业已完成但进程未加入。执行这个时候,3个过程后

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) 

打印,他们会停下来,他们成为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) 
+0

塞德里克,我遇到的问题是只有一个孩子会跑,而其他人成为僵尸。 问题btw原来是Postgres – sudharsh 2011-04-30 07:45:57

+0

@sudharsh的僵局,你是否设法追踪并克服了僵局? – pkaleta 2013-01-31 16:48:59