【问题标题】:Ending a process when a tcp connection is closed关闭 tcp 连接时结束进程
【发布时间】:2012-08-02 20:27:46
【问题描述】:

我正在开发一个客户端-服务器应用程序,每当新客户端连接到服务器时,服务器都会使用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 模块中使用线程还是留在进程中会更有益吗?正在开发服务器代码,以便在具有“平均”规格的服务器上大量使用(如何优化此设置)。

【问题讨论】:

    标签: python sockets tcp process


    【解决方案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 有一个超时来知道是否有新的连接,即使没有新的连接,清除也会以更规律的间隔发生。

    【讨论】:

    • 我明白你把进程放在一个列表中的意思,但是你是什么意思定期调用加入一个小的超时?另外,这是否是在 python 中使用进程而不是线程来处理套接字的一般方法?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-20
    • 1970-01-01
    • 1970-01-01
    • 2018-06-14
    • 2018-12-27
    • 1970-01-01
    • 2022-01-20
    相关资源
    最近更新 更多