From fa03f6c863c35204af5b618454f530dc5094ccff Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Mon, 5 Dec 2011 01:32:29 +0100 Subject: Remove the outdated notion that multithreading doesn't work well on Unices. --- Doc/howto/sockets.rst | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/Doc/howto/sockets.rst b/Doc/howto/sockets.rst index 04e9b98..3d8ade9 100644 --- a/Doc/howto/sockets.rst +++ b/Doc/howto/sockets.rst @@ -395,19 +395,13 @@ Performance There's no question that the fastest sockets code uses non-blocking sockets and select to multiplex them. You can put together something that will saturate a -LAN connection without putting any strain on the CPU. The trouble is that an app -written this way can't do much of anything else - it needs to be ready to -shuffle bytes around at all times. - -Assuming that your app is actually supposed to do something more than that, -threading is the optimal solution, (and using non-blocking sockets will be -faster than using blocking sockets). Unfortunately, threading support in Unixes -varies both in API and quality. So the normal Unix solution is to fork a -subprocess to deal with each connection. The overhead for this is significant -(and don't do this on Windows - the overhead of process creation is enormous -there). It also means that unless each subprocess is completely independent, -you'll need to use another form of IPC, say a pipe, or shared memory and -semaphores, to communicate between the parent and child processes. +LAN connection without putting any strain on the CPU. + +The trouble is that an app written this way can't do much of anything else - +it needs to be ready to shuffle bytes around at all times. Assuming that your +app is actually supposed to do something more than that, threading is the +optimal solution, (and using non-blocking sockets will be faster than using +blocking sockets). Finally, remember that even though blocking sockets are somewhat slower than non-blocking, in many cases they are the "right" solution. After all, if your -- cgit v0.12 From 834545117011acd4272e96b2885d590037548aa4 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Mon, 5 Dec 2011 01:37:34 +0100 Subject: Use www.python.org instead of a hostname pointing to a parked (or squatted) domain. Also, reformat a bit. --- Doc/howto/sockets.rst | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/Doc/howto/sockets.rst b/Doc/howto/sockets.rst index 3d8ade9..603df59 100644 --- a/Doc/howto/sockets.rst +++ b/Doc/howto/sockets.rst @@ -60,11 +60,10 @@ Creating a Socket Roughly speaking, when you clicked on the link that brought you to this page, your browser did something like the following:: - #create an INET, STREAMing socket + # create an INET, STREAMing socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - #now connect to the web server on port 80 - # - the normal http port - s.connect(("www.mcmillan-inc.com", 80)) + # now connect to the web server on port 80 - the normal http port + s.connect(("www.python.org", 80)) When the ``connect`` completes, the socket ``s`` can be used to send in a request for the text of the page. The same socket will read the @@ -75,13 +74,11 @@ exchanges). What happens in the web server is a bit more complex. First, the web server creates a "server socket":: - #create an INET, STREAMing socket - serversocket = socket.socket( - socket.AF_INET, socket.SOCK_STREAM) - #bind the socket to a public host, - # and a well-known port + # create an INET, STREAMing socket + serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + # bind the socket to a public host, and a well-known port serversocket.bind((socket.gethostname(), 80)) - #become a server socket + # become a server socket serversocket.listen(5) A couple things to notice: we used ``socket.gethostname()`` so that the socket @@ -101,10 +98,10 @@ Now that we have a "server" socket, listening on port 80, we can enter the mainloop of the web server:: while True: - #accept connections from outside + # accept connections from outside (clientsocket, address) = serversocket.accept() - #now do something with the clientsocket - #in this case, we'll pretend this is a threaded server + # now do something with the clientsocket + # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run() -- cgit v0.12 From 8e644f0e7c566b2b03461e21ae3fa3af159acfc9 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Mon, 5 Dec 2011 01:43:32 +0100 Subject: Reword IPC section --- Doc/howto/sockets.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Doc/howto/sockets.rst b/Doc/howto/sockets.rst index 603df59..f2da397 100644 --- a/Doc/howto/sockets.rst +++ b/Doc/howto/sockets.rst @@ -123,12 +123,13 @@ IPC --- If you need fast IPC between two processes on one machine, you should look into -whatever form of shared memory the platform offers. A simple protocol based -around shared memory and locks or semaphores is by far the fastest technique. +pipes or shared memory. If you do decide to use AF_INET sockets, bind the +"server" socket to ``'localhost'``. On most platforms, this will take a +shortcut around a couple of layers of network code and be quite a bit faster. -If you do decide to use sockets, bind the "server" socket to ``'localhost'``. On -most platforms, this will take a shortcut around a couple of layers of network -code and be quite a bit faster. +.. seealso:: + The :mod:`multiprocessing` integrates cross-platform IPC into a higher-level + API. Using a Socket -- cgit v0.12 From 5b73ca4b3d5d53f949636eb5678ea31569adbdba Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Mon, 5 Dec 2011 01:46:35 +0100 Subject: s/SOCKSTREAM/TCP/ --- Doc/howto/sockets.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/sockets.rst b/Doc/howto/sockets.rst index f2da397..e2703f5 100644 --- a/Doc/howto/sockets.rst +++ b/Doc/howto/sockets.rst @@ -298,7 +298,7 @@ When Sockets Die Probably the worst thing about using blocking sockets is what happens when the other side comes down hard (without doing a ``close``). Your socket is likely to -hang. SOCKSTREAM is a reliable protocol, and it will wait a long, long time +hang. TCP is a reliable protocol, and it will wait a long, long time before giving up on a connection. If you're using threads, the entire thread is essentially dead. There's not much you can do about it. As long as you aren't doing something dumb, like holding a lock while doing a blocking read, the -- cgit v0.12