《再谈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的大小相当。
(完)