Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么时间睡眠不受GIL的影响?_Python_Gil - Fatal编程技术网

Python 为什么时间睡眠不受GIL的影响?

Python 为什么时间睡眠不受GIL的影响?,python,gil,Python,Gil,我在研究Python GIL时了解到,一次只能执行一个线程(无论谁持有锁)。然而,如果这是真的,那么为什么这段代码只需要3秒就可以执行,而不是15秒呢 import threading import time def worker(): """thread worker function""" time.sleep(3) print 'Worker' for i in range(5): t = threading.Thread(target=worker)

我在研究Python GIL时了解到,一次只能执行一个线程(无论谁持有锁)。然而,如果这是真的,那么为什么这段代码只需要3秒就可以执行,而不是15秒呢

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()
根据对线程的直觉,我会认为这需要3秒钟,确实如此。然而,在了解了GIL和一个线程可以同时执行之后,现在我看了这段代码并想,为什么不花15秒呢?

时间。睡眠(3)
并不等同于循环运行3秒,在保持GIL锁的同时消耗CPU周期。该线程将从中切换3秒钟,允许其他线程运行

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()
请参阅为什么
时间。睡眠
不是CPU密集型操作。总之,线程将挂起,直到超时结束

由于所有线程都处于休眠状态,因此没有在CPU上执行任何实际工作,而且GIL锁并不禁止这些线程同时工作,因为从一开始就没有持有持久锁


当有多个线程执行CPU密集型工作时,需要考虑GIL锁。在这种情况下,您会看到预期的减速。GIL不会导致纯IO绑定工作的任何放缓。

马里奥的答案是一个很好的高水平答案。如果您对如何实现的一些细节感兴趣:在CPython中,
time.sleep
的实现将其
select
系统调用包装为
Py\u BEGIN\u ALLOW\u THREADS
/
Py\u END\u ALLOW\u THREADS

这些是在释放/获取GIL时保存和恢复线程状态的宏:


我认为
sleep()
确实释放了GIL。此外,Python每隔N毫秒或在执行M个字节码指令后强制执行一次线程切换(取决于使用的是哪个版本的Python)。@martineau如果这是真的,那么“等待”在哪里发生?我认为线程最终会并行等待。睡眠线程不会执行。5个线程一次休眠并不是一次执行的。在这里包含CPython源代码非常有趣,这将给它一个很好的阅读机会。