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 回答