5

Manager オブジェクトを使用multiprocessingしてサーバーを作成し、そのサーバーにリモート接続する場合、クライアントはリモート サーバーへの接続を維持する必要があります。クライアントがシャットダウンする前にサーバーがなくなった場合、クライアントはサーバーの予想されるアドレスに永遠に接続しようとします。

クライアント プロセスが終了しないため、サーバーがなくなった後に終了しようとしているクライアント コードでデッドロックが発生しています。

サーバーがダウンする前にdelリモート オブジェクトとクライアント マネージャを削除すると、プロセスは正常に終了しますが、使用直後にクライアントのマネージャ オブジェクトとリモート オブジェクトを削除するのは理想的とは言えません。

それが私にできる最善のことですか?リモート マネージャ オブジェクトから切断する別の (より適切な) 方法はありますか? サーバーがダウンしたり、接続が失われたりした後、クライアントをきれいに終了する方法はありますか?

socket.setdefaulttimeout が multiprocessing で機能しないことは知っていますが、特に multiprocessing モジュールの接続タイムアウトを設定する方法はありますか? これは私が問題を抱えているコードです:

from multiprocessing.managers import BaseManager
m = BaseManager(address=('my.remote.server.dns', 50000), authkey='mykey')
# this next line hangs forever if my server is not running or gets disconnected
m.connect()

更新これはマルチプロセッシングで壊れています。接続タイムアウトはソケット レベルで発生する必要があります (そして、これを行うにはソケットがノンブロッキングである必要があります) が、ノンブロッキング ソケットはマルチプロセッシングを中断します。リモートサーバーが利用できない場合、接続を断念することはできません。

4

2 に答える 2

1

マルチプロセッシング モジュールの接続タイムアウトを具体的に設定する方法はありますか?

はい、しかしこれはハックです。より大きな python-fu を持つ誰かがこの答えを改善できることを願っています。マルチプロセッシングのタイムアウトは、次のように定義されていmultiprocessing/connection.pyます。

# A very generous timeout when it comes to local connections...
CONNECTION_TIMEOUT = 20.
...
def _init_timeout(timeout=CONNECTION_TIMEOUT):
        return time.time() + timeout

_init_timeout具体的には、次のようにメソッドにモンキーパッチを適用することで、それを機能させることができました。

import sys
import time

from multiprocessing import managers, connection

def _new_init_timeout():
    return time.time() + 5

sys.modules['multiprocessing'].__dict__['managers'].__dict__['connection']._init_timeout = _new_init_timeout
from multiprocessing.managers import BaseManager
m = BaseManager(address=('somehost', 50000), authkey='secret')
m.connect()

ここで、5 は新しいタイムアウト値です。もっと簡単な方法があれば、きっと誰かが指摘してくれるでしょう。そうでない場合、これはマルチプロセッシング開発チームへの機能リクエストの候補になる可能性があります。タイムアウトを設定するのと同じくらい基本的なことは、これよりも簡単だと思います。一方で、API でタイムアウトを公開しないという哲学的な理由がある場合もあります。

それが役立つことを願っています。

于 2012-03-30T04:00:16.483 に答える
0

これはあなたを助けることができますか?

#### TEST_JOIN_TIMEOUT

def join_timeout_func():
    print '\tchild sleeping'
    time.sleep(5.5)
    print '\n\tchild terminating'

def test_join_timeout():
    p = multiprocessing.Process(target=join_timeout_func)
    p.start()

    print 'waiting for process to finish'

    while 1:
        p.join(timeout=1)
        if not p.is_alive():
            break
        print '.',
        sys.stdout.flush()

(python 16.6 ページから取得)

通常、タイムアウトは while ループでテストされます。

于 2011-08-29T13:24:03.377 に答える