Problem in multithreading Socketserver explained (should apply to *nix, too)
Gerson Kurz
gerson.kurz at t-online.de
Wed Aug 29 02:02:31 EDT 2001
The BaseHTTPServer is derived from SocketServer.TCPServer.
This class serves up data using the handle_request() member function.
It looks like this (comments added by me):
-----------------------
def handle_request(self):
try:
request, client_address = self.get_request()
except socket.error:
return
if self.verify_request(request, client_address):
try:
# this will start a new thread
self.process_request(request, client_address)
except:
self.handle_error(request, client_address)
# this will close the socket still in use by the new thread
self.close_request(request)
-----------------------
The ThreadingTCPServer, which can be mixed in at a higher point in the
hierarchy, overloads self.process_request() to startup a new thread
for that request. However, once the thread has started, if the thread
running self.handle_request() gets the CPU before the other thread has
finished reading from the request, it will close the request, even
while a thread serving the request is running in the background.
And, self.close_request() closes the socket, so the error message
about _sock being a number is completely explainable.
So I don't think just adding ThreadingTCPServer could've worked from
the start; and the same problem could possibly happen on the *nix
implementation of ThreadingTCPServer, too.
Solution:
1) the derived TCPServer has to implement close_request(self) as a
stub function
2) the request class has to implement handle() and at the end of the
function, close the socket.
More information about the Python-list
mailing list