0

I'm new in python programming and socket, so I've started with the example of a asynchronous (threading) SocketServer at http://docs.python.org/2/library/socketserver.html.

The example for the ThreadingMixIn class works well, however I have 2 questions for the experts:

  • Each new connection creates a new thread, fine. But it seems like the threads never terminate even if the connection on the other side closes as the thread number just increases.

  • Second question is about the handle method. I've tried to send 2 consecutive messages with sendall from my client, but the second send fails... It appears that in fact the handle method waits for the first message and then terminates. I had to add a 'while 1:' for getting to work.

So to conclude, I've the feeling this example is useless and bad as it just creates a thread only able to receive one single message. If at least it would terminate by itself, but it doesn't seem to be the case for me...

Thanks for your inputs!

Here's the code for the server:

import threading
import SocketServer

class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):

    def handle(self):
        data = self.request.recv(1024)
        cur_thread = threading.current_thread()
        response = "{}: {}".format(cur_thread.name, data)
        self.request.sendall(response)

class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass


if __name__ == "__main__":

    server = ThreadedTCPServer(('localhost', 13009), ThreadedTCPRequestHandler)

    # Start a thread with the server -- that thread will then start one
    # more thread for each request
    server_thread = threading.Thread(target=server.serve_forever)
    # Exit the server thread when the main thread terminates
    server_thread.daemon = True
    server_thread.start()
    print "Server loop running in thread:", server_thread.name

    raw_input("Hit enter to stop the server")

    server.shutdown()

And the client's code:

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost', 13009))
try:
    sock.sendall('hello\n')
    response = sock.recv(1024)
    print "Received: {}".format(response)

    # A second 'send' will generate an error on Windows.
    # On Mac, no error but the received message is empty as the
    # handle method in the server isn't called for each new message
    sock.sendall('how are you?')
    response = sock.recv(1024)
    print "Received: {}".format(response)

except socket.error, (value,message):
    print "Error: " + message

finally:
    sock.close()

As you can see, each time you run the client's code, a new thread is created even though the previous socket had been closed... or at least, threading.current_thread() returns a new ID. How can I check that the previous thread is stopped?

1
  • Can you include the code you've written? Commented Sep 5, 2014 at 15:02

2 Answers 2

1

In regards to @luka's answer; Dietrich is correct in that using threads this way is fine. Yes, you can only execute one python instruction at a given time, but sockets are typically I/O bound anyway so it is all good.

The easiest way to know a thread is dead is not directly from python as this is somewhat abstracted away with the interface you are using. Instead I would look to the operating system which can provide this information. On Linux, just execute the pstree command. Your thread count should be displayed as something like <thread count>*[{process name}], where thread count is the count of your threads.

Other methods include having your application print "stating thread", then "ending thread", or using the python debugged (pydb).

In regards to the last point raised by @luka about event driven python, it is kind of premature optimization. If you are not expecting a huge load on your application don't worry about it. If you are expecting a huge load then the forking of a thread per request could become a bottleneck that would need to be addressed.

Sign up to request clarification or add additional context in comments.

Comments

0
  1. Python is running from single thread so using multiple threads doesn’t give you any performance boost if this is your aim. It will likely unecessary spend more memory.
  2. I recommend using gevent library to abstract parallel execution and handling large number of sockets.

http://www.gevent.org/

3 Comments

Python can run from multiple threads, but the GIL ensures that only one thread is executing Python code at a time. Other threads can execute system calls or long-running foreign functions.
Is that any better than running event loop (single threded)
If you use threads, your IO code will be significantly less complicated than if you use an event loop. So yes, it could be much better. But it depends on the application.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.