0

プログラムで並列処理を行うためにマルチプロセッシング モジュールを使用しています。マルチプロセス間で共有 dict オブジェクトを取得したいのですが、マルチプロセスが正常に閉じられている場合は取得できますが、CTRL+C を押すと取得できませんでした。 、どうすれば目標を達成できますか? 次のように私のコード

#!/usr/bin/python
from multiprocessing import Process, Manager, Pool
import os
import signal
import time

def init_worker():
    signal.signal(signal.SIGINT, signal.SIG_IGN)

def run_worker(i,my_d):
    print 'Work Started: %d %d' % (os.getpid(), i)
    for j in range(5):
        print j
        tmp1 = str(i) + str(j)
        my_d[tmp1] = j
        time.sleep(1)

def main():
    print "Initializng 3 workers"
    pool = Pool(3, init_worker)

    manager = Manager()
    my_d = manager.dict()
    try:
        for i in range(3):
            pool.apply_async(run_worker,args=(i,my_d))
        pool.close()
        pool.join()
        print my_d
# When process is closed normally, I could get the my_d successfully

    except KeyboardInterrupt:
        print "Caught KeyboardInterrupt, terminating workers"
        pool.terminate()
        pool.join()
        print my_d
#When process is closed by Ctrl+C, couldn't I get the my_d ?

if __name__ == "__main__":
    main()
4

2 に答える 2

0

マルチプロセッシングのManager -Objectからの共有ディクショナリが必要です。

ここでこの同様の質問を参照してください(最初の回答): Pythonマルチプロセッシング:複数のプロセス間でdictを共有するにはどうすればよいですか?

于 2012-09-16T11:38:48.557 に答える
0

親プロセスを中断したときに生成されるエラーを見てください。

Caught KeyboardInterrupt, terminating workers
<DictProxy object, typeid 'dict' at 0x801abe150; '__str__()' failed>

に変更print "Caught KeyboardInterrupt, terminating workers"してみるprint len(my_d)と、何が起こるかを詳細に確認できます。これは、ワーカーのプールを終了/結合する前の状態であることに注意してください。

Traceback (most recent call last):
  File "manager-test.py", line 39, in <module>
    main()
  File "manager-test.py", line 33, in main
    print len(my_d)
  File "<string>", line 2, in __len__
  File "/usr/local/lib/python2.7/multiprocessing/managers.py", line 755, in _callmethod
    self._connect()
  File "/usr/local/lib/python2.7/multiprocessing/managers.py", line 742, in _connect
    conn = self._Client(self._token.address, authkey=self._authkey)
  File "/usr/local/lib/python2.7/multiprocessing/connection.py", line 169, in Client
    c = SocketClient(address)
  File "/usr/local/lib/python2.7/multiprocessing/connection.py", line 293, in SocketClient
    s.connect(address)
  File "/usr/local/lib/python2.7/socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
socket.error: [Errno 2] No such file or directory

メイン プログラムを中断すると、子プロセスからマネージャへの接続が切断されます。これにより、マネージャー (およびマネージャーが管理するオブジェクト) が使用できない状態になります。マネージャから子プロセスへのソケット接続が機能しなくなったため、プロキシはデータを取得できません。

データを失うことなく実行時間の長いプロセスを中断したい場合は、もっと慎重に行う必要があると思います。このようなもの:

import select
import sys

print 'Type q<enter> it you want to quit...'
while True:
    r, foo, bla = select.select([sys.stdin], [], [], 1)
    if len(r):
        what = sys.stdin.readline()
        if 'q' in what:
            print 'bye!'
            break;
    # E.g. check on the progress of your calculation here
# Close and join the pool here, and do other clean-up.
于 2012-09-16T12:44:26.240 に答える