【Python】多线程编程
1、thread模块
2、threading模块
3、Queue模块与多线程互斥
简介:
thread和threading模块允许创建和管理线程,thread模块提供了基本的线程和锁的支持,而threading提供了更高级别,功能更强的线程管理功能,Queue模块
允许创建一个可以用于多个线程之间共享数据的队列数据结构
1.thread模块
Thread模块常用函数:
实例1:
# encoding:utf-8 ''' Created on 2014-6-23 @author: Administrator ''' from time import ctime, sleep import thread loops = [4, 2] def loop(index, nsecs, lock): print "start loop,%s at:%s" % (index, ctime()) sleep(nsecs) print "loop %s done at:%s" % (index, ctime()) lock.release() def main(): print "all starting at :%s" % ctime() locks = [] nlocks = range(len(loops)) for i in nlocks: lock = thread.allocate_lock() lock.acquire() locks.append(lock) for i in nlocks: thread.start_new_thread(loop, (i, loops[i], locks[i])) for i in nlocks: while locks[i].locked(): pass print "all done at:%s" % ctime() if __name__ == "__main__": main()
2.threading模块
threading模块包含对象:
threading模块Thread类,常用函数:
使用threading.Thread类可以用多种方法创建线程:
一、创建一个Thread的实例,参数为一个函数
二、创建一个Thread的实例,参数为一个可调用的类对象
三、从Thread派生出一个子类,创建一个这个子类的实例
方法一:创建一个Thread的实例,参数为一个函数
# encoding:utf-8 ''' Created on 2014-6-23 @author: Administrator ''' import threading from time import ctime, sleep loops = [4, 2] def loop(nloop, nsec): print "strating loop %s at:%s" % (nloop, ctime()) sleep(nsec) print "end loop %s at:%s" % (nloop, ctime()) def main(): print threading.__file__ print "all start at:%s" % ctime() threads = [] nloops = range(len(loops)) for i in nloops: t = threading.Thread(target=loop, args=(i, loops[i]))#创建一个Thread实例,传递一个函数 threads.append(t) for i in nloops: threads[i].start() for i in nloops: threads[i].join() print "all end at:%s" % ctime() if __name__ == "__main__": main()
方法二:创建一个Thread的实例,参数为一个可调用的类对象
# encoding:utf-8 ''' Created on 2014-6-24 @author: Administrator ''' import threading from time import sleep, ctime loops = [4, 2] class ThreadingCls(object): def __init__(self, func, args, name=''): self.name = name self.func = func self.args = args #python 可调用对象,重写__call__方法,通过ThreadingCls(...)调用 def __call__(self): self.func(*self.args) #函数调用,参数为元组*(...) def loop(nloop, nsec): print "staring loop %s at:%s" % (nloop, ctime()) sleep(nsec) print "end loop %s at:%s" % (nloop, ctime()) def main(): print "all start at:%s" % ctime() threads = [] nloops = range(len(loops)) for i in nloops: t = threading.Thread(target=ThreadingCls(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 end at:%s" % ctime() if __name__ == "__main__": main()
方法三:从Thread派生出一个子类,创建一个这个子类的实例
# encoding:utf-8 ''' Created on 2014-6-24 @author: Administrator ''' import threading from time import sleep, ctime loops = [4, 2] """ 子类化Thread创建多线程: (1)构造函数__init__需要调用基类的构造函数 (2)需要重写run方法 """ class ThreadingDerived(threading.Thread): def __init__(self, func, args, name=''): super(ThreadingDerived, self).__init__() self.name = name self.func = func self.args = args def run(self): print "%s running at:%s" % (self.name, ctime()) self.func(*self.args) def loop(nloop, nsec): print "staring loop %s at:%s" % (nloop, ctime()) sleep(nsec) print "end loop %s at:%s" % (nloop, nsec) def main(): print "all start at:%s" % ctime() threads = [] nloops = range(len(loops)) for i in nloops: t = ThreadingDerived(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 end at:%s" % ctime() if __name__ == "__main__": main()
3、Queue模块与多线程互斥
Queue模块常用函数:
实例3. 生产者消费者
# encoding:utf-8 ''' Created on 2014-6-24 @author: Administrator ''' from threading_subcls import ThreadingDerived from Queue import Queue from time import ctime, sleep from random import randint gl_queue = Queue(3) def consumer(): while True: if gl_queue.empty(): sleep(2) else: print "consum %s at:%s" % (gl_queue.get(1), ctime()) #get函数,从队列中取一个对象,block=1,函数会一直阻塞直到队列有空间为止 def producer(): while True: if gl_queue.full(): sleep(2) else: pdata = randint(0, 3) gl_queue.put(pdata, 1) #把pdata放入队列,block=1,函数会一直阻塞到队列有空间为止 print "produce %s at:%s" % (pdata, ctime()) def main(): funcs = [consumer, producer] ncount = range(len(funcs)) threads = [] for i in ncount: t = ThreadingDerived(funcs[i], (), funcs[i].__name__) threads.append(t) for i in ncount: threads[i].start() for i in ncount: threads[i].join() if __name__ == "__main__": main()
线程互斥:Python主要有四种数据同步机制:互斥锁(Lock),条件变量(Condition), 信号量(Semaphore)和同步队列,在threading模块中锁对象用threading.Lock()创建
实例4.
# encoding:utf-8 ''' Created on 2014-6-24 @author: Administrator ''' import threading from threading_subcls import ThreadingDerived from time import sleep gl_lock = threading.Lock() #互斥锁 gl_count = 0 gl_max = 3 def consumer(): global gl_count, gl_lock while True: gl_lock.acquire() if gl_count > 0: gl_count -= 1 print "consume %s-->%s" % (gl_count + 1, gl_count) gl_lock.release() else: gl_lock.release() print "%s wait producer..." % threading.current_thread().getName() sleep(3) def producer(): global gl_count, gl_lock, gl_max while True: if gl_count >= gl_max: sleep(1) continue gl_lock.acquire() gl_count += 1 print "produce %s-->%s" % (gl_count - 1, gl_count) gl_lock.release() def main(): funcs = [consumer, consumer, producer] ncount = range(len(funcs)) threads = [] for i in ncount: t = ThreadingDerived(funcs[i], (), "%s#%s" % (funcs[i].__name__, i)) threads.append(t) for i in ncount: threads[i].start() for i in ncount: threads[i].join() if __name__ == "__main__": main()