问题
From what I understood when doing research on the Python GIL, is that only one thread can be executed at the once (Whoever holds the lock). However, if that is true, then why would this code only take 3 seconds to execute, rather than 15 seconds?
import threading
import time
def worker():
"""thread worker function"""
time.sleep(3)
print 'Worker'
for i in range(5):
t = threading.Thread(target=worker)
t.start()
By intuition about threads, I would have thought this would take 3 seconds, which it does. However after learning about the GIL and that one thread can be executing at once, now I look at this code and think, why does it not take 15 seconds?
回答1:
Mario's answer is a good high level answer. If you're interested in some details of how this is implemented: in CPython, the implementation of time.sleep
wraps its select
system call with Py_BEGIN_ALLOW_THREADS
/ Py_END_ALLOW_THREADS
:
https://github.com/python/cpython/blob/7ba1f75f3f02b4b50ac6d7e17d15e467afa36aac/Modules/timemodule.c#L1880-L1882
These are macros that save and restore the thread state, while releasing/acquiring the GIL:
https://github.com/python/cpython/blob/7c59d7c9860cdbaf4a9c26c9142aebd3259d046e/Include/ceval.h#L86-L94 https://github.com/python/cpython/blob/4c9ea093cd752a6687864674d34250653653f743/Python/ceval.c#L498
回答2:
time.sleep(3)
is not equivalent to a loop running for 3 seconds, burning CPU cycles while holding the GIL lock. The thread is switched away from for 3 seconds, allowing other threads to run.
See this stackoverflow question as to why time.sleep
isn't a CPU intensive operation. To summarize, the thread is suspended until the timeout has elapsed.
Because all threads are sleeping, no real work on the CPU is being done, and the GIL lock doesn't prohibit these threads from working at the same time since no persistent lock was held to begin with.
The GIL lock comes into consideration when you have multiple threads doing CPU-intensive work. In that type scenario, you would see the slowdown you expect. The GIL does not cause any slowdowns in purely IO-bound work.
来源:https://stackoverflow.com/questions/61809897/why-does-time-sleep-not-get-affected-by-the-gil