closing a "forever" Server Socket

Laszlo Nagy gandalf at designaproduct.biz
Mon Jan 22 13:52:17 EST 2007


alessandro írta:
> Oh my God! it's really so complicated?
>
> 3 modules (threading, SocketServer, select) only for design a way to
> shutdown a TCP server????
> ...but they told me that python was easy... :)
>   
I believe that SockerServer was created for testing purposes, although 
there are some programs using it in production. Yes, Python is easy. The 
language is very clear, and you do not need to install third party 
modules in order to create a server. :-) Of course the easiest way is to 
call serve_forever. Isn't it easy? The other way is to implement your 
own message handling loop. The SocketServer is flexible enough to do 
this; and I don't think it is complicated. 7 lines of code will allow 
you to stop the server safely from anywhere, even from other threads. 
Try to implement the same in C or Delphi...
> but it doesen't work because the server remain alive...maybe
> SocketServer create immortal server...
> I need only to close my application, there is a way to force the server
> thread to close?
>   
In pure Python, no. Python threads are "cooperative". In other words, 
they cannot be terminated from outside. A thread will stop after the 
execution exits its "run" method. (You can, of course terminate the 
tread with an operating system function, but it is not recommended.)


Here is a class that can be stopped with an event:

import threading

stop_requested = threading.Event()

class SoftWaitThread(threading.Thread):
    """SoftWaitThread can wait for a given time except if the thread was 
asked
        to terminate itself."""
    def waitsome(self,amount=10):
        """Wait the specified amount of time.

        This can be terminated by stop_requested within 0.1 seconds."""
        for idx in range(int(10*amount)):
            time.sleep(0.1)
            if stop_requested.isSet():
                break


Then you can do this:

class MyServerThread(SoftWaitThread):
    def run(self):
       server = MySocketServerClass()
       srvfd = server.fileno()
       while not stop_requested.isSet():
          ready = select.select([srvfd], [], [], 1)
          if srvfd in ready[0]:

        server.handle_request()
     else:
        pass

      
And then:

import time
def main():
    sth = MyServerThread() # Create your thread
    sth.start() # Start handling requests in another thread
    try:  
        time.sleep(TIMEOUT_IN_SECONDS)  # Wait...
    finally:
        stop_requested.set() # Request the server thread to stop itself
        sth.join() # Wait until the server thread stops
    print "Stopped."

You could start several threads and request them to stop with the same 
event. I hope this helps.

   Laszlo


p.s.: Not all of the above was tested, be careful.




More information about the Python-list mailing list