3

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が、そうではないようです。明らかな何かが欠けていますか?

4

1 に答える 1

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)
于 2011-04-28T07:36:36.073 に答える