转自:python核心编程第18章
Python提供了几个用于多线程编程的模块,包括thread, threading和Queue等。thread模块提供了基本的线程和锁的支持。threading模块提供了更高级别,功能更强的线程管理功能。Queue模块可以创建一个多个线程之间共享数据的队列。
建议使用threading模块,避免使用thread模块。有以下几个原因:一是threading模块更为高级,对线程的支持更加完善,而thread模块的属性可能会与threading模块出现冲突;二是thread模块的同步原语只有一个,而threading模块有很多;三是thread模块对于进程何时结束完全没有控制,当主线程结束时,所有的子线程会被强制结束掉,没有警告也没有正常的清楚工作,而threading模块能够确保重要的子线程结束后进程才退出。
thread模块不支持守护线程。当主线程退出时,所有的子线程不论它们是否还在工作,都会被强行退出。threading模块支持守护线程。什么是守护线程呢?守护线程一般是一个等待客户请求的服务器,如果没有客户提出请求,它就一直等着。如果设定一个线程为守护线程,就表示这个线程是不重要的,在进程退出时,不用等待这个线程退出。
我们可以使用threading模块的Thread类来创建线程,它有很多thread模块中没有的函数。下面介绍三种利用Thread类创建线程的方法。
一、 创建一个Thread类的实例,传递给它一个函数
实例:
#create a thread with a function
import threading
from time import sleep, ctime
loops = [4,2]
def loop(nloop, nsec):
print 'start loop', nloop, 'at:', ctime()
sleep(nsec)
print 'loop', nloop, 'done at:', ctime()
def main():
print 'starting at:', ctime()
threads=[]
nloops = range(len(loops))
for i in nloops:
#create the thread with the function, target= function name, args = function arguments
t = threading.Thread(target=loop, args=(i, loops[i]))
threads.append(t)
for i in nloops: #start threads
threads[i].start()
for i in nloops: #wait for all
threads[i].join()
print 'all done at', ctime()
if __name__ == '__main__':
main()
二、创建一个Thread类的实例,传递给它一个可调用的类对象
实例:
#create a thread with a class instance
import threading
from time import sleep, ctime
loops=[4, 2]
#create a class named ThreadFunc, extend object
class ThreadFunc(object):
#init this class, it has 3 arguments, they are function, function arguments, function name
def __init__(self, func, args, name=''):
self.name = name
self.func = func
self.args = args
def __call__(self):
apply(self.func, self.args)
def loop(nloop, nsec):
print 'start loop', nloop, 'at:', ctime()
sleep(nsec)
print 'loop', nloop, 'done at:', ctime()
def main():
print 'starting at:', ctime()
threads = []
nloops = range(len(loops))
for i in nloops:
# create a thread with an instance. target = ThreadFunc instance.
t = threading.Thread(target=ThreadFunc(loop,(i,loops[i]),loop.__name__))
threads.append(t)
for i in nloops: #start threads
threads[i].start()
for i in nloops: #wait for all
threads[i].join()
print 'all done at', ctime()
if __name__ == '__main__':
main()
三、从Thread类派生出一个子类,创建这个子类的实例
实例:
# create a thread by extending the thread class
import threading
from time import sleep, ctime
loops=(4, 2)
#create a class named MyThread which extends Thread
class MyThread(threading.Thread):
#init the class with 3 parameters, they are function, function arguments, function name
def __init__(self, func, args, name=''):
threading.Thread.__init__(self)
self.name = name
self.func = func
self.args = args
def run(self):
apply(self.func, self.args)
def loop(nloop, nsec):
print 'start loop', nloop, 'at:', ctime()
sleep(nsec)
print 'loop', nloop, 'done at:', ctime()
def main():
print 'starting at:', ctime()
threads = []
nloops = range(len(loops))
for i in nloops:
#get the thread instance
t = MyThread(loop,(i,loops[i]),loop.__name__)
threads.append(t)
for i in nloops: #start threads
threads[i].start()
for i in nloops: #wait for all
threads[i].join()
print 'all done at', ctime()
if __name__ == '__main__':
main()