Python 通过两个标准库 thread 和 threading 提供对线程的支持。thread 提供了低级别的、原始的线
程以及一个简单的锁。threading 基于 Java 的线程模型设计。锁(Lock)和条件变量(Condition)在 Java
中是对象的基本行为(每一个对象都自带了锁和条件变量),而在 Python 中则是独立的对象。
trheading 模块
我们应该避免使用 thread 模块,原因是它不支持守护线程。当主线程退出时,所有的子线程不论它
们是否还在工作,都会被强行退出。有时我们并不期望这种行为,这时就引入了守护线程的概念。threading
模块则支持守护线程。所以,我们直接使用 threading 来改进上面的例子。
threads.py
#coding=utf-8
import threading
from time import sleep, ctime
#音乐播放器
def music(func):
for i in range(2):
print "I was listening to %s! %s" %(func,ctime())
sleep(2)
#视频播放器
def move(func):
for i in range(2):
print "I was at the %s! %s" %(func,ctime())
sleep(5)
#创建线程数组
threads = []
#创建线程 t1,并添加到线程数组
t1 = threading.Thread(target=music,args=(u'爱情买卖',))
threads.append(t1)
#创建线程 t2,并添加到线程数组
t2 = threading.Thread(target=move,args=(u'阿凡达',))
threads.append(t2)
if __name__ == '__main__':
#启动线程
for i in threads:
i.start()
#守护线程
for i in threads:
i.join()
print 'all end: %s' %ctime()
import threading 引入线程模块。
threads = [] 创建线程数组,用于装载线程。
threading.Thread()通过调用 threading 模块的 Thread()方法来创建线程。
class threading.Thread()说明:
class threading.Thread(group=None, target=None, name=None, args=(), kwargs={})
This constructor should always be called with keyword arguments. Arguments are:
group should be None; reserved for future extension when a ThreadGroup class is implemented.
target is the callable object to be invoked by the run() method. Defaults to None, meaning nothing is
called.
name is the thread name. By default, a unique name is constructed of the form “Thread-N” where N is a
small decimal number.
args is the argument tuple for the target invocation. Defaults to ().
kwargs is a dictionary of keyword arguments for the target invocation. Defaults to {}.
If the subclass overrides the constructor, it must make sure to invoke the base class constructor
(Thread.__init__()) before doing anything else to the thread.
start() 开始线程活动。
join() 等待线程终止。
通过 for 循环遍历 thread 数组中所装载的线程;然后通过 start()函数启动每一个线程。
join()会等到线程结束,或者在给了 timeout 参数的时候,等到超时为止。join()的另一个比较重
要的方面是它可以完全不用调用。一旦线程启动后,就会一直运行,直到线程的函数结束,退出为止。
运行结果:
Python Shell
>>> ================================ RESTART ================================
>>>
I was listening to 爱情买卖! Sun Feb 15 10:17:09 2015
I was at the 阿凡达! Sun Feb 15 10:17:09 2015
I was listening to 爱情买卖! Sun Feb 15 10:17:11 2015
I was at the 阿凡达! Sun Feb 15 10:17:14 2015
all end: Sun Feb 15 10:17:19 2015
从上面的运行结果可以看出,两个子线程(music 、 move)同时启动于 17 分 09 秒,直到所有线程
结束于 17 分 19 秒,总耗时为 10 秒。move 的两次电影循环需要 10 秒,music 的歌曲循环需要 4 秒,从执
行结果可以看出两个线程真正达到了并行工作。