Thanks to everyone who has answered, I think I'm slowly starting to get it now. Let's see if we can come up with a toy example that doesn't involve low-level socket programming :-)
Let me simulate a slow function call: import random, time def work(id): print("starting with id", id) workload = random.randint(5, 15) for i in range(workload): time.sleep(0.2) # pretend to do some real work print("processing id", id) # let the user see some progress print("done with id", id) return 10 + id pending = [1, 2, 3, 4] for i, n in enumerate(pending): pending[i] = work(n) How do I write work() so that it cooperatively multi-tasks with other ... threads? processes? what the hell do we call these things? What does this example become in the asynchronous world? In this case, all the work is pure computation, so I don't expect to save any time by doing this, because the work is still all being done in the same process/thread, not in parallel. It may even take a little bit longer, due to the overhead of switching from one to another. (I presume that actual disk or network I/O may be better, because the OS will run the I/O in parallel if possible, but I don't expect that in this case.) Am I getting close? -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list