Python multiprocessing and sockets do not close

I experience strange behavior when using multiprocessing and socket in Python. I am dealing with a piece of code similar to the one I post below (I simplified a lot by trying to be naive).

Three processes appear in the code: one process does nothing, another process launches a third, which will listen on the socket. If I terminated the listener process, the socket still remains open (I see it there with netstat).

  • If I delete (or stop) the DoNothing process, it works.
  • If I switch everything to threading.Thread, it works, but
  • If I leave DoNothing as a process and switch the server and Launcher to threading.Thread, the problem will not go away.

Can someone tell me why the socket is still open? Is there a problem with multiprocessing and sockets?

I am using python 2.6.6 running on Linux.

Thanks a lot, Alvaro.

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)

EDIT:

Corresponding netstat -lnpconclusion:

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

I noticed that the pid shown in netstat changes from the parent process (when the process server starts) to Launcher (when the server is stopped).

+3
source share
2 answers

To fix the immediate problem (do not disconnect from the socket), add self.s.shutdown(socket.SHUT_RDWR)to the method Server.stop:

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

multiprocessing, , , Process (.. fork). , , , bind. , , .

, , self.s (bind et al), Server.run?

+1

Source: https://habr.com/ru/post/1781492/


All Articles