使用多线程编程和一个共享的数据结构如queue,这种程序任务可以用多个功能单一的线程来组织:
UserRequestThread:负责读取客户的输入,可能是一个I/O信道。程序可能创建多个线程,每个客户一个,请求会被放入队列中
RequestProcessor:一个负责从队列中获取并处理请求的线程,它为下面那种线程提供输出
ReplyThread:负责把给用户的输出取出来,如果是网络应用程序就把结果发送出去,否则就保存到本地文件系统或数据库中。
一个顺序执行单线程的例子:
from time import sleep,ctime def loop0(): print "start loop0 at:",ctime() sleep(4) print"loop0 done at",ctime() def loop1(): print"start loop 1 at:",ctime() sleep(2) print"loop 1 done at:",ctime() def main(): print"starting at:",ctime() loop0() loop1() print"all done at:",ctime() if __name__==‘__main__‘: main()
thread模块
函数:
start_new_thread(function,args,kwargs=None) 产生一个新的线程,在新线程中用指定的参数和可选的kwargs来调用这个函数
allocate_lock() 分配一个LockType类型的锁对象
exit() 让线程退出
LockType类型锁对象方法
acquire(wait=None) 尝试获取锁对象
locked() 如果获取了锁对象返回true,否则返回false
release()释放锁
注意:start_new_thread()要求一定要有前两个参数,即使想要运行的函数不要参数,也要传一个元组
使用多线程的例子
import thread from time import sleep,ctime def loop0(): print "start loop0 at:",ctime() sleep(4) print"loop0 done at",ctime() def loop1(): print"start loop 1 at:",ctime() sleep(2) print"loop 1 done at:",ctime() def main(): print"starting at:",ctime() thread.start_new_thread(loop0,()) thread.start_new_thread(loop1,()) sleep(6) print"all done at:",ctime() if __name__==‘__main__‘: main()
使用锁和多线程:
import thread from time import sleep,ctime loops=[4,2] def loop(nloop,nsec,lock): print"start loop",nloop,"at:",ctime() sleep(nsec) print"loop",nloop,"done at:",ctime() lock.release() def main(): print"starting at:",ctime() locks=[] nloops=range(len(loops)) for i in nloops: lock=thread.allocate_lock() lock.acquire() locks.append(lock) for i in nloops: thread.start_new_thread(loop,(i,loops[i],locks[i])) for i in nloops: while locks[i].locked(): pass print "all done at:",ctime() if __name__==‘__main__‘: main()
threading模块
threading模块对象:
Thread 表示一个线程的执行对象
Lock 锁原语对象
RLock 可重入锁对象 ,使单线程可以再次获得已经获得的锁(递归锁定)
Condition条件变量对象,能让一个线程停下来,等待其他线程满足了某个条件
Event 通用的条件变量,多个线程可以等待某个事件的发生,在事件发生后,所有的线程都会被激活
Semaphore 为等待锁的线程提供一个类似等候室的结构
BoundedSemaphore 与Semaphore类似,只是它不允许超过初始值‘
Timer 与Thread类似,只是它要等待一段时间后才开始运行
Thread类创建线程的方法:
1.创建一个Thread的实例,传给它一个函数
2.创建一个Thread的实例,传给它一个可调用的类对象
3.从Thread派生出一个子类,创建这个子类的一个实例
Thread对象的函数
start() 开始线程的执行
run() 定义线程的功能的函数(一般会被子类重写)
join(timeout=None) 线程挂起,直到线程结束;如果给了timeout,则最多阻塞timeout秒
getName() 返回线程的名字
setName() 设置线程的名字
setDaemon(daemonic) 把线程的daemon标志设为daemonic(一定要在调用start()函数前调用)
创建一个Thread的实例,传给它一个函数
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: t=threading.Thread(target=loop,args=(i,loops[i])) threads.append(t) for i in nloops: threads[i].start() for i in nloops: threads[i].join() print "all done at:",ctime() if __name__==‘__main__‘: main()
创建一个Thread实例,传给它一个可调用的类对象:
import threading from time import sleep,ctime loops=[4,2] class ThreadFunc(object): 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: t=threading.Thread(target=ThreadFunc(loop,(i,loops[i]))) threads.append(t) for i in nloops: threads[i].start() for i in nloops: threads[i].join() print "all done at:",ctime() if __name__==‘__main__‘: main()
从Thread派生出一个子类,创建这个子类的一个实例
import threading from time import sleep,ctime loops=[4,2] class MyThread(threading.Thread): def __init__(self,func,args,name=""): threading.Thread.__init__(self) 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: t=MyThread(loop,(i,loops[i]),loop.__name__) threads.append(t) for i in nloops: threads[i].start() for i in nloops: threads[i].join() print "all done at:",ctime() if __name__==‘__main__‘: main()
Queue模块函数
queue(size) 创建一个大小为size的Queue对象
qsize()返回队列的大小
empty() 如果队列为空返回True,否则返回False
full() 如果队列已满返回True,否则返回False
put(item,block=0) 把item放到队列中,如果给了block(不为0),函数会一直阻塞到队列中有空间为止
get(block=0) 从队列中取一个对象,如果给了block(不为0),函数会一直阻塞到队列中有对象为止
Queue模块可以用来进行线程间通讯,让各个线程之间共享数据