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