一提到多线程一般大家的第一感觉就是可以提升程序性能,在实际的操作中往往遇到性能的问题,都尝试使用多线程来解决问题,但多线程程序并不是在任何情况下都能提升效率,在一些情况下恰恰相反,反而会降低程序的性能。这里给出两个简单的例子来说明下:
程序1:
1 import threading 2 from time import ctime 3 4 class MyThread(threading.Thread): 5 def __init__(self, func, args, name): 6 threading.Thread.__init__(self) 7 self.name = name 8 self.func = func 9 self.args = args 10 11 def run(self): 12 print 'starting', self.name, 'at:',ctime() 13 apply(self.func, self.args) 14 print self.name, 'finished at:', ctime() 15 16 def fun1(x): 17 y = 0 18 for i in range(x): 19 y+=1 20 21 def fun2(x): 22 y = 0 23 for i in range(x): 24 y+=1 25 26 def main(): 27 print 'staring single thread at:',ctime() 28 fun1(10000000) 29 fun2(10000000) 30 print 'finished single thread at:',ctime() 31 32 t1 = MyThread(fun1,(10000000,),fun1.__name__) 33 t2 = MyThread(fun2,(10000000,),fun2.__name__) 34 t1.start() 35 t2.start() 36 t1.join() 37 t2.join() 38 39 print 'all done' 40 41 if __name__ == '__main__': 42 main()
该程序执行结果为:
staring single thread at: Sat Dec 08 10:27:11 2012
finished single thread at: Sat Dec 08 10:27:14 2012
starting fun1 at: Sat Dec 08 10:27:14 2012
starting fun2 at: Sat Dec 08 10:27:14 2012
fun1 finished at:Sat Dec 08 10:27:21 2012
fun2 finished at:Sat Dec 08 10:27:21 2012
all done
结果显示对于同样的问题多线程耗费了多一倍的时间,fun1,、fun2都是计算型程序,这就意味着两个代码都需要占用CPU资源,虽然采用了多线 程但CPU资源是唯一的(不考虑多CPU多核的情况),同一时刻只能一个线程使用,导致多线程无法真正的并发,相反由于线程的切换的开销,效率反而有明显 的下降。由此看以在单CPU的场景下对于计算密集型的程序,多线程并不能带来效率的提升。
程序2:
1 import threading 2 from time import ctime 3 4 class MyThread(threading.Thread): 5 def __init__(self, func, args, name): 6 threading.Thread.__init__(self) 7 self.name = name 8 self.func = func 9 self.args = args 10 11 def run(self): 12 print 'starting', self.name, 'at:',ctime() 13 apply(self.func, self.args) 14 print self.name, 'finished at:', ctime() 15 16 def fun1(x): 17 for i in range(x): 18 fd = open('1','w') 19 fd.close() 20 21 def fun2(x): 22 y = 0 23 for i in range(x): 24 y+=1 25 26 def main(): 27 print 'staring single thread at:',ctime() 28 fun1(15000) 29 fun2(50000000) 30 print 'finished single thread at:',ctime() 31 32 t1 = MyThread(fun1,(15000,),fun1.__name__) 33 t2 = MyThread(fun2,(50000000,),fun2.__name__) 34 t1.start() 35 t2.start() 36 t1.join() 37 t2.join() 38 39 print 'all done' 40 41 if __name__ == '__main__': 42 main()
该程序执行结果为:
staring single thread at: Sat Dec 08 11:03:30 2012
finished single thread at: Sat Dec 08 11:03:46 2012
starting fun1 at: Sat Dec 08 11:03:46 2012
starting fun2 at: Sat Dec 08 11:03:46 2012
fun2 finished at: Sat Dec 08 11:03:55 2012
fun1 finished at: Sat Dec 08 11:03:58 2012
all done
结果显示这个程序采用多线程比单线程的效率有明显的提升。这是由于fun1主要是文件的操作,fun2是计算操作,单线程的情况下,虽然两个程序主 要使用不同的资源但是在线程内部只能串行执行,在IO操作的时候,CPU实际是无事可做。多线程的情况下,如果一个线程在等待IO操作,线程会马上调度到 另外一个线程上,并发的使用了不同的资源。
结论:
线程本身由于创建和切换的开销,采用多线程不会提高程序的执行速度,反而会降低速度,但是对于频繁IO操作的程序,多线程可以有效的并发。
对于包含不同任务的程序,可以考虑每个任务使用一个线程。这样的程序在设计上相对于单线程做所有事的程序来说,更为清晰明了,比如生产、消费者问题。
在实际的开发中对于性能优化的问题需要考虑到具体的场景来考虑是否使用多线程技术。