0

新しいクライアントがサーバーに接続するたびに、サーバーがmultiprocessingモジュールを使用して新しいプロセスを生成するクライアントサーバーアプリケーションを開発しています。そのターゲット関数は、ソケットを取得して I/O を実行する関数です。私が抱えている問題は、クライアントとサーバー上のプロセスの間で TCP 接続が閉じられると、子プロセスを終了するために .join() 関数呼び出しをどのように/どこに配置すればよいですか? また、C のように親プロセスで waitpid を実行する必要がありますか?

サーバーコード:

def new_client(conn_socket):
    while True:
        message = conn_socket.recv(BUFFER_SIZE)
        conn_socket.send(message)  
        #just echo the message
        #how to check to see if the TCP connection is still alive?
        #put the .join() here??



def main():
    #create the socket
    server_socket = socket(AF_INET,SOCK_STREAM)

    #bind the socket to the local ip address on a specific port and listen
    server_port = 12000                               
    server_socket.bind(('',server_port))
    server_socket.listen(1)

    #enter in a loop to accept client connections
    while True:
        connection_socket, client_address = server_socket.accept()       
        #create a new process with the new connection_socket
        new_process = Process(target = new_client, args = (connection_socket,))
        new_process.start()
        #put the .join() here or what??

if __name__ == '__main__':
    main()

threadまた、このセットアップでは、モジュールでスレッドを使用するか、プロセスにとどまる方が有益でしょうか? サーバーコードは、「平均的な」仕様のサーバーで頻繁に使用するために開発されています (このセットアップを最適化する方法)。

4

1 に答える 1

1

の戻り値を確認する必要がありますrecv。ゼロが返された場合、接続は適切に閉じられています。負の場合は、エラーが発生しています。

また、join呼び出しは、サブプロセスを作成するプロセス内にある必要があります。joinただし、引数を指定しないと、サブプロセスが完了するまで呼び出しプロセスがブロックされるため、注意してください。プロセスをリストに入れ、join短いタイムアウトで定期的に呼び出します。

編集:最も簡単な方法は、無限受け入れループの最後に追加して、プロセスのリストを反復処理し、それがis_alive. そうでない場合は、呼び出しjoinてリストから削除します。

何かのようなもの:

all_processes = []
while True:
    connection_socket, client_address = server_socket.accept()       
    #create a new process with the new connection_socket
    new_process = Process(target = new_client, args = (connection_socket,))
    new_process.start()

    # Add process to our list
    all_processes.append(new_process)

    # Join all dead processes
    for proc in all_processes:
        if not proc.is_alive():
            proc.join()
    # And remove them from the list
    all_processes = [proc for proc in all_processes if proc.is_alive()]

古いプロセスのパージは、新しい接続を取得した場合にのみ発生することに注意してください。新しい接続を頻繁に取得するかどうかに応じて、これには時間がかかる場合があります。リッスンしているソケットをノンブロッキングにし、たとえばselectタイムアウトを使用して、新しい接続があるかどうかを知ることができます。新しい接続がない場合でも、パージはより定期的に行われます。

于 2012-08-02T06:40:32.373 に答える