python - 由 multiprocessing.Manager() 启动的服务器进程使管道套接字不会立即关闭

标签 python python-3.x sockets multiprocessing

我有以下代码,服务器接受网络连接,将它传递给子进程以使用 Manager().Queue() 进行处理:

q = Manager().Queue()

class Server:

    def run(self, host, port):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.bind((host, port))
        s.listen(1)

        print('parent', os.getpid())

        while True:
            c, _ = s.accept()
            q.put(c)
            c.close()

def handle_request():
    print('child', os.getpid())
    while True:
        c = q.get()
        time.sleep(1)
        print(c.recv(4))
        c.close()

Process(target=handle_request, args=()).start()
Server().run('127.0.0.1', 10000)   

close 没有按预期工作,我认为这是因为 Manager 的服务器进程仍然对该套接字有引用,lsof -i 确认。如何处理?我发现没有办法关闭 Manager 进程中的套接字,shutdown 可以解决问题,但不是我想要的。

最佳答案

有趣的问题。

我不确定这是否有任何帮助,但我发现您的代码一开始有些奇怪,因为使用 Manager().Queue() 将套接字对象发送到另一个进程听起来不正常喜欢它是支持的。可能是,但是将文件描述符发送到另一个进程需要几个步骤。我稍微更改了您的代码以按照我的方式去做 - 基本上减少和重建句柄。

from multiprocessing import Manager, Process
from multiprocessing.reduction import reduce_handle, rebuild_handle
import socket
import os
from time import sleep

q = Manager().Queue()


class Server:
    def run(self, host, port):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind((host, port))
        s.listen(1)

        print('parent', os.getpid())

        while True:
            c, _ = s.accept()
            foo = reduce_handle(c.fileno())
            q.put(foo)
            c.close()


def handle_request():
    print('child', os.getpid())
    while True:
        bar = q.get()
        sleep(1)
        barbar = rebuild_handle(bar)
        c = socket.fromfd(barbar, socket.AF_INET, socket.SOCK_STREAM)
        print(c.recv(4))
        c.shutdown(socket.SHUT_RDWR)

Process(target=handle_request, args=()).start()
Server().run('127.0.0.1', 10000)

至少在我运行它时,它不会在 CLOSE_WAIT 中留下任何套接字,而且它的工作方式与我预期的一样。

关于python - 由 multiprocessing.Manager() 启动的服务器进程使管道套接字不会立即关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46815868/

相关文章:

node.js - OpenShift 中的网络套接字连接

c# - Tcp Listener 套接字仅用于建立连接或处理所有传入数据?

php - 如何正确使用 PHP 监听传入的套接字连接?

python - 来自 Python 脚本的 Django runserver

python - heroku postgresql 不会 syncdb

python - 循环列表与范围时的行为差异

python - 当尝试在任何地方定义全局变量时,我得到 'invalid syntax'

python - 在单个 for 循环中访问两个或多个列表

python - Pandas `drop_duplicates` 不保留第一行

python-3.x - 删除 Pandas 数据框中的列