1. 10

  2. 3

    The entire article implies and treats concurrency as if it is the same concept as parallelism…

    1. 3

      Thank you for your critique! As far as I understand the two concepts, parallelism is a special case of concurrency. If you can indicate the text passages that you find confusing, I will be happy to rewrite them more precisely.

      1. 1

        I think that they are completely separate things, but - regardless - the confusing part is that the entire article is about parallelism and is referring to it as concurrency. This can cause a lot of confusion to people who may not know the difference.

        There’s no specific passage, it’s just inherently awkward terminology.

    2. 2

      Great article! Could you add a sentence explaining why the threaded version has a speedup despite the GIL? If it were just that “threads are spawned” then it should take just as long as the ‘map’ version.

      1. 11

        In case anyone’s genuinely wondering and doesn’t want to wait, the explanation is that the GIL is not the all-devouring monster most people assume it is. The GIL is a lock on the interpreter and its C API; pure-Python threads release it whenever they block on I/O, and C extensions can release it whenever they’re executing code that doesn’t require the interpreter/C-API.

        Which in turn means that the GIL is mostly an issue for workloads which are both CPU-bound and pure Python. The example in the article is pure Python, but it’s I/O-bound, so threading does speed it up significantly.

        1. 3

          That‘s a great explanation, I couldn’t have put it better.

      2. 1

        Thanks a lot for the post. How does this approach compare to the “multiprocessing” module ?

        1. 2

          You’re welcome! The standard library’s multiprocessing module is around since Python 2, while concurrent.futures was added in Python 3.2. They both can be used to achieve multithreading / multiprocessing, but doing so they leverage different coding patterns. As implied by the name, concurrent.futures yields futures objects. If you know some JavaScript, you might be familiar with promises - futures and promises are quite similar. On the other hand, multiprocessing is the right choice for more oldschool concurrency patterns such as the consumer-producer problem.

        2. 1

          How to run parallel/multithreaded without map. I want to run socket server in “one” thread and send receive with the client in the “main” thread. Is it possible?

          1. 1

            That’s absolutely possible! The map - pattern is just a neat trick to come up with simple, easy to read code. To do what you just described you want to use daemon threads. Check out Raymond Hettinger’s talk Thinking about Concurrency, he gives a great introduction.