《再谈Python的GIL》这篇文件中漏掉了一个很重要的函数没有讨论到:sys.setcheckinterval
该函数用于设置GIL自动切换的间隔,默认值为100,之前的测试都是在默认值下得出来的结果,接下来我们来再通过例子做个实验,将checkinterval设置成1000,看下是什么情况
3.1 测试用例:
from threading import Thread
from threading import Event as TEvent
from multiprocessing import Process
from multiprocessing import Event as PEvent
from timeit import Timer
import sys
sys.setcheckinterval(1000) #(100000)
def countdown(n,event):
while n > 0:
n -= 1
event.set()
def io_op(n,event,filename):
f = open(filename,'w')
while not event.is_set():
f.write('hello,world')
f.close()
def t1():
COUNT=100000000
event = TEvent()
thread1 = Thread(target=countdown,args=(COUNT,event))
thread1.start()
thread1.join()
def t2():
COUNT=100000000
event = TEvent()
thread1 = Thread(target=countdown,args=(COUNT//2,event))
thread2 = Thread(target=countdown,args=(COUNT//2,event))
thread1.start(); thread2.start()
thread1.join(); thread2.join()
def t3():
COUNT=100000000
event = PEvent()
p1 = Process(target=countdown,args=(COUNT//2,event))
p2 = Process(target=countdown,args=(COUNT//2,event))
p1.start(); p2.start()
p1.join(); p2.join()
def t4():
COUNT=100000000 #00000
event = TEvent()
thread1 = Thread(target=countdown,args=(COUNT,event))
thread2 = Thread(target=io_op,args=(COUNT,event,'thread.txt'))
thread1.start(); thread2.start()
thread1.join(); thread2.join()
def t5():
COUNT=100000000 #00000
event = PEvent()
p1 = Process(target=countdown,args=(COUNT,event))
p2 = Process(target=io_op,args=(COUNT,event,'process.txt'))
p1.start(); p2.start()
p1.join(); p2.join()
if __name__ == '__main__':
t = Timer(t1)
print('countdown in one thread:%f'%(t.timeit(1),))
t = Timer(t2)
print('countdown use two thread:%f'%(t.timeit(1),))
t = Timer(t3)
print('countdown use two Process:%f'%(t.timeit(1),))
t = Timer(t4)
print('countdown in one thread with io op in another thread:%f'%(t.timeit(1),))
t = Timer(t5)
print('countdown in one process with io op in another process:%f'%(t.timeit(1),))
输出:
countdown in one thread:7.867444
countdown use two thread:9.830585
countdown use two Process:2.148110
countdown in one thread with io op in another thread:7.691811
countdown in one process with io op in another process:7.477607
结论:
是的,countdown在多线程情况下的效率得到了极大的提升,原因就线程的有效运行率大大提高了,当切换到线程时,线程得以运行的机会提高了。
但是这会导致I/O的性能大大的降低。thread.txt的大小为2161KB,而process.txt的大小则为22401KB
而在checkinterval值为默认值100时则thread.txt和process.txt的大小相当。
(完)