Search code examples
pythonmultithreadingblocking

Computationally-heavy Thread is "hanging" in Python 3 - Why is that?


I am relatively new to Python, but a little skilled at coding. This little piece of code is driving me crazy. Why on earth is the method summe() so stubborn in a Thread? The Threads seem to be processed sequentially. That means, every next Thread is only started if the previous one has come to an end. I don't know why? All four Threads should start "parallelly" and work "parallelly". Even if they are running only on a single Core due to the restrictions of GIL.

The same procedure with the method count() works "parallelly" as intended.

Dear Internet, please help me!…

Paul:)

#!/usr/bin/python3

import threading

# Hanging...
def summe(n):
    print("Start")
    s = sum(range(n))
    print("Done")

# Works like a charm
def count(n):
    print("Start")
    while n > 0:
        n = n-1
    print("Done")

# This works
for i in range(3):
    threading.Thread(target=count,args=(10000000000000,)).start()

# This hangs...
for i in range(3):
    threading.Thread(target=summe,args=(10000000000000,)).start()

Solution

  • Due to the GIL, a built-in function like sum is atomic; once it starts, it won't be interrupted until it completes. While it is possible that the threading system could choose to execute only the first line of summe before switching context to allow the next thread to start, it is highly unlikely. The "hang" you see is sum in the first thread blocking until it finally completes.

    In count, on the other hand, there is no one long atomic operation that blocks on the GIL; just lots (and lots and lots and ...) of small operations, which allows lots of opportunity to start each thread and return to the main thread. Using a much smaller value for n, you can see each count thread start, then a few moments later they will complete. Likewise, you can observe the three summe threads run almost serially (in one test I ran, the first ran to completion before starting the other two running in parallel).