17.2.5 底层线程支持
sys包括一些用于控制和调试线程行为的底层函数。
17.2.5.1 切换间隔
Python3使用一个全局锁来防止单个线程破坏解释器状态。一个时间间隔之后(这个时间间隔是可配置的),字节码执行会暂停,解释器检查是非需要执行某个信号处理器。在这个间隔检查期间,当前线程还会释放全局解释器锁(Global Interpreter Lock,GIL),然后从新请求,使其他线程比释放这个锁的线程更优先。默认的切换间隔是5毫秒,可以用sys.getswitchinterval()获取当前值。用
sys.getswitchinterval()改变这个间隔可能会对应用的性能产生影响,这取决于所完成的操作。
import sys
import threading
from queue import Queue
def show_thread(q):
for i in range(5):
for j in range(1000000):
pass
q.put(threading.current_thread().name)
return
def run_threads():
interval = sys.getswitchinterval()
print('interval = {:0.3f}'.format(interval))
q = Queue()
threads = [
threading.Thread(target=show_thread,
name='T{}'.format(i),
args=(q,))
for i in range(3)
]
for t in threads:
t.setDaemon(True)
t.start()
for t in threads:
t.join()
while not q.empty():
print(q.get(),end=' ')
print()
return
for interval in [0.001,0.1]:
sys.setswitchinterval(interval)
run_threads()
print()
当切换间隔小于线程完成运行所要花费的时间时,解释器会把控制权交给另一个线程,让它运行一段时间。这种行为从下面的第一组输出情况可以看到,其中间隔被设置为1毫秒。
如果有更长的间隔,那么在强制交出控制之前,活动线程能完成更多工作。这种情况可以用第二个例子中队列内的name值顺序来说明,这里使用的间隔为10毫秒。
除了切换间隔,还有很多其他隐式也会控制Python线程的上下文切换。例如,如果一个线程完成I/O,则它会释放GIL,并且可能因此允许另一个线程接管执行。