Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Time.sleep seems to be blocking main thread, not just child thread?

I'm running the following code:

from threading import Thread
from time import sleep

def file_write(file_input, num_lines):
    sleep(10)
    file = open("testfile.txt", "w")
    for line in num_lines:
        file.write("{}: {}".format(line, file_input))

    file.close()


if __name__ == '__main__':
    curr_thread = Thread(target=file_write, args=("Norah", range(5)))
    curr_thread.daemon = False
    curr_thread.start()

The expectation is the main thread will exit immediately, because I don't call join. But it doesn't. Do sleep calls block the main thread too?

EDIT: There is a similar question asked in this thread: time.sleep -- sleeps thread or process? but it's not the same.
I looked at the thread: it says that sleep doesn't cause child processes to block each other, but it doesn't say what happens to the main thread. When I ran the code from the accepted answer, the main thread did not exit immediately, as I thought it would.

UPDATE: Looks like multithreading won't solve my problem: the aim is to run a bunch of tasks in the background. I'm using the subprocess module instead now.

like image 928
Norah Borus Avatar asked Sep 21 '17 18:09

Norah Borus


People also ask

Does time sleep block all threads?

In a single threaded application, this means everything is blocked while you sleep. In a multithreaded application, only the thread you explicitly 'sleep' will block and the other threads still run within the process.

Does time sleep release Gil?

Model #3: Non-Python code can explicitly release the GILIf we run time. sleep(3) , that will do nothing for 3 seconds. We saw above that long-running extension code can prevent the GIL from being automatically switched between threads.

Why thread sleep is not recommended Java?

Thread. sleep is bad! It blocks the current thread and renders it unusable for further work.


1 Answers

Sleep calls only block the thread in which they're called. Printing anything in the main thread immediately after the call to curr_thread.start() will prove this to you.

However, if you interrupt your code (Ctrl-C), you'll see a useful stack trace. The last call is inside the threading module's _shutdown() method, which appears to be waiting for all non-daemon threads to finish.

t = _pickSomeNonDaemonThread()
while t:
    t.join()
    t = _pickSomeNonDaemonThread()

And reading the documentation for the threading module, you can see that: "The entire Python program exits when no alive non-daemon threads are left." So, because you've done curr_thread.daemon = False, you're forcing the main thread to wait for this thread to finish first.

I should point out, though, that threads inherit the "daemon-ness" of their parents. Since the main thread is never a daemon thread, you could have left off the curr_thread.daemon = False, and you'd get the same behavior.

like image 107
bnaecker Avatar answered Oct 07 '22 02:10

bnaecker