本文研究利用Python中提供的threading模块,实现Python多线程编程的一些入门技巧。
MULTITHREADED
在多线程编程出现之前,程序是一个执行序列,按顺序在CPU中运行的,即使程序的子任务之间相互独立,也要按顺序执行。为了提高效率,能将各种本质上就是异步的子任务做并行处理的编程方式应运而生了,这就是多线程编程。
线程有时也被称为轻量级进程,具有开始、顺序执行、结束三部分。与进程不同,线程之间可以直接共享运行的结果,所以线程可以用一个指令指针来记录自己运行到什么地方,然后通过中断或是睡眠的方式,让步给其他线程,这种快速的切换就让使用者感觉程序是在并行执行了。Python解释器要实现多线程,也必须在执行多个线程的同时,保证在任意时刻,在解释器中运行的线程也只有一个。要实现这个目标依靠的是全局解释锁GIL,线程在运行前先设置一个GIL,运行结束后再将它解锁。
Python中主要使用threading模块来产生线程和锁,利用Queue模块在线程间进行通信。
threading module
假设有两个函数,thread1和thread2,thread1需要工作4秒,thread2需要工作5秒,按顺序执行就需要9秒:
#!/usr/bin/env python
from time import sleep, ctime
def thread1():
print 'Thread1 start at:', ctime()
sleep(4)
print 'Thread1 done at:', ctime()
def thread2():
print 'Thread2 start at:', ctime()
sleep(5)
print 'Thread2 done at:', ctime()
def main():
print 'Main start at:', ctime()
thread1()
thread2()
print 'Main end at:',ctime()
if __name__ == '__main__':
main()
运行结果为:
Main start at: Thu Oct 14 13:31:14 2010
Thread1 start at: Thu Oct 14 13:31:14 2010
Thread1 done at: Thu Oct 14 13:31:18 2010
Thread2 start at: Thu Oct 14 13:31:18 2010
Thread2 done at: Thu Oct 14 13:31:23 2010
Main done at: Thu Oct 14 13:31:23 2010
Thread1 start at: Thu Oct 14 13:31:14 2010
Thread1 done at: Thu Oct 14 13:31:18 2010
Thread2 start at: Thu Oct 14 13:31:18 2010
Thread2 done at: Thu Oct 14 13:31:23 2010
Main done at: Thu Oct 14 13:31:23 2010
接下来利用threading模块的Thread类,让两个程序同时执行。首先实例化Thread类,将两个函数名(thread1和thread2)作为参数传入,创建一个线程。当所有线程创建结束后启动,调用join()函数来控制线程锁。
#!/usr/bin/env python
import threading
from time import sleep, ctime
def thread1():
print 'Thread1 start at:', ctime()
sleep(4)
print 'Thread1 done at:', ctime()
def thread2():
print 'Thread2 start at:', ctime()
sleep(5)
print 'Thread2 done at:', ctime()
def main():
print 'Main start at:', ctime()
t1 = threading.Thread(target=thread1)
t2 = threading.Thread(target=thread2)
t1.start()
t2.start()
t1.join()
t2.join()
print 'Main done at:',ctime()
if __name__ == '__main__':
main()
运行的总时间缩短为5秒:
Main start at: Thu Oct 14 14:19:05 2010
Thread1 start at: Thu Oct 14 14:19:05 2010
Thread2 start at: Thu Oct 14 14:19:05 2010
Thread1 done at: Thu Oct 14 14:19:09 2010
Thread2 done at: Thu Oct 14 14:19:10 2010
Main done at: Thu Oct 14 14:19:10 2010
Thread1 start at: Thu Oct 14 14:19:05 2010
Thread2 start at: Thu Oct 14 14:19:05 2010
Thread1 done at: Thu Oct 14 14:19:09 2010
Thread2 done at: Thu Oct 14 14:19:10 2010
Main done at: Thu Oct 14 14:19:10 2010