【问题标题】:Python multiprocessing and sockets not being closedPython多处理和套接字未关闭
【发布时间】:2010-12-21 17:03:53
【问题描述】:

在 Python 上使用多处理和套接字时,我遇到了一个奇怪的行为。我正在处理一段与我在下面发布的代码类似的代码(我已经简化了很多事情试图变得天真)。

这段代码产生了三个进程:一个进程什么都不做,另一个进程启动第三个,它将监听一个套接字。如果我终止“侦听器”进程,套接字仍然保持打开状态(我可以通过 netstat 看到它)。

  • 如果我删除(或停止)“DoNothing”进程,这将有效。
  • 如果我将所有内容都切换到 threading.Thread,这可行,但是
  • 如果我将 DoNothing 保留为进程并将服务器和启动器切换到 threading.Thread,问题仍然存在。

有没有人暗示为什么套接字仍然打开?处理多处理和套接字有什么问题吗?

我使用的是在 Linux 上运行的 python 2.6.6。

非常感谢, 阿尔瓦罗。

import time
from multiprocessing import Process, Event

import socket

class Server(Process):
    def __init__(self, port):
        super(Server, self).__init__()

        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.s.bind(("127.0.0.1",port))
        self.s.listen(1)
        self.s.settimeout(10)
        self.is_stop = Event()
        self.is_stop.clear()

    def run(self):
        while not self.is_stop.is_set():
            print "Server: running (pid %s)" % self.pid 
            time.sleep(1)
        print "Server: exiting"

    def stop(self):
        self.is_stop.set()
        self.s.close()

class Launcher(Process):
    def __init__(self):
        super(Launcher, self).__init__()
        self.srv = Server(9999)
        self.srv.start()

    def run(self):
        print "Launcher pid %s" % self.pid
        while True:
            time.sleep(1)

    def stop(self):
        print "Launcher: I'm stopping the server"
        self.srv.stop()
        self.srv.terminate()
        self.srv.join()
        print "Launcher: server stopped"

class DoNothing(Process):
    def __init__(self):                
        super(DoNothing, self).__init__()

    def run(self):
        while True:
            time.sleep(1)


l = Launcher()
l.start()

dn = DoNothing()
dn.start()

time.sleep(2)

print " Stop launcher "
l.stop()

while True:
    time.sleep(1)

编辑:

相关netstat -lnp输出:

tcp        0      0 127.0.0.1:9999          0.0.0.0:*               LISTEN      7183/python

我注意到 netstat 中显示的 pid 从父进程(当进程服务器正在运行时)更改为启动器的进程(当服务器停止时)。

【问题讨论】:

  • netstat输出的相关行是什么?
  • 我已经用它更新了原始帖子(我完全忘记了!)。

标签: python multithreading sockets process multiprocessing


【解决方案1】:

要解决直接问题(套接字未关闭),请将self.s.shutdown(socket.SHUT_RDWR) 添加到Server.stop 方法中:

def stop(self):
    self.is_stop.set()
    self.s.shutdown(socket.SHUT_RDWR) 
    self.s.close()

【讨论】:

【解决方案2】:

我不是multiprocessing 包的专家,但似乎Process 构造函数是在父进程 的上下文中调用的(即在fork 之前)。如果是这种情况,那么它是您的层次结构中执行bind 的最顶层进程。子进程可能会继承套接字。

如果您将处理 self.sbind 等)的所有内容移至 Server.run,会发生什么?

【讨论】:

  • 感谢您的提示。这种行为(即在父进程上创建的套接字)不存在于原始脚本中(我已经简化了很多,并且很快重写了它)。唯一改变的是拥有套接字的进程,但行为仍在继续一样的。
猜你喜欢
  • 1970-01-01
  • 2018-04-07
  • 2018-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-23
  • 2017-01-31
  • 1970-01-01
相关资源
最近更新 更多