Python 多线程编程,thread
来源:互联网 发布:大叔与女孩的网络电影 编辑:程序博客网 时间:2024/05/16 07:27
Python提供了thread模块,threading模块与queue模块进行多线程编程。queue模块用于线程间的通信,前两者可以创建线程,不过由于thread模块偏底层,需要手动去完成很多任务,而且同步机制不如threading模块好用,所以建议选择threading模块。
threading模块中,选择Thread类来创建线程(三种方法):创建一个Thread的实例,并传入一个函数;创建一个Thread的实例,并传入一个可调用的类对象;从Thread派生出一个子类,创建一个这个子类的实例。(代码来自core Python programming)(Python3.3)
创建一个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 test():
- 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() #当前process或者thread遇到join()函数时会暂停(挂起),直到这个join()函数连接的thread结束;join(timeout=None)中的timeout参数如果设置了,则会等到设置的时间长度,直到超时或者thread结束,开始运行接下来的代码
- print('all done at',ctime())
- if __name__=='__main__':
- test()
结果:
- >>>
- starting at: Thu Aug 15 01:34:20 2013
- start loopstart loop 01 atat Thu Aug 15 01:34:20 2013Thu Aug 15 01:34:20 2013
- loop 1 done at: Thu Aug 15 01:34:22 2013
- loop 0 done at: Thu Aug 15 01:34:24 2013
- all done at Thu Aug 15 01:34:25 2013
创建一个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):
- self.func(*self.args)
- def loop(nloop, nsec):
- print('start loop',nloop,'at',ctime())
- sleep(nsec)
- print('loop',nloop,'done at:',ctime())
- def test():
- print('starting at:',ctime())
- threads=[]
- nloops=range(len(loops))
- for i in nloops:
- t=threading.Thread(target=ThreadFunc(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__':
- test()
结果:
- >>>
- starting at: Thu Aug 15 01:58:32 2013
- start loopstart loop 01 atat Thu Aug 15 01:58:32 2013Thu Aug 15 01:58:32 2013
- loop 1 done at: Thu Aug 15 01:58:34 2013
- loop 0 done at: Thu Aug 15 01:58:36 2013
- all done at Thu Aug 15 01:58:36 2013
从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 run(self):
- self.func(*self.args)
- def loop(nloop, nsec):
- print('start loop',nloop,'at',ctime())
- sleep(nsec)
- print('loop',nloop,'done at:',ctime())
- def test():
- 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__':
- test()
结果:
- >>>
- starting at: Thu Aug 15 02:15:18 2013
- start loopstart loop 1 at Thu Aug 15 02:15:18 2013
- 0 at Thu Aug 15 02:15:18 2013
- loop 1 done at: Thu Aug 15 02:15:20 2013
- loop 0 done at: Thu Aug 15 02:15:22 2013
- all done at Thu Aug 15 02:15:22 2013
单线程、多线程速度对比:
对多线程使用第三者创建线程的方法。计算斐波纳挈、阶乘、累加和的结果:
首先,编写一个单独的模块myThread.py,专门生成线程,然后使用的时候,只需要import myThread 就可以了。
- import threading
- from time import sleep,ctime
- class MyThread(threading.Thread):
- def __init__(self,func,args,name=''):
- threading.Thread.__init__(self)
- self.name=name
- self.func=func
- self.args=args
- def getResult(self):
- return self.res
- def run(self):
- print('starting',self.name,'at:',ctime())
- self.res=self.func(*self.args)
- print(self.name,'finished at:',ctime()) #end of module myThread
- from myThread import MyThread
- from time import ctime,sleep
- def fib(x):
- sleep(0.005)
- if x<2:
- return 1
- return (fib(x-2)+fib(x-1))
- def fac(x):
- sleep(0.1)
- if x<2:
- return 1
- return (x*fac(x-1))
- def sumF(x):
- sleep(0.1)
- if x<2:
- return 1
- return (x+sumF(x-1))
- funcs=[fib, fac, sumF]
- n=12
- def test():
- nfuncs=range(len(funcs))
- print('***SINGLE THREAD')
- for i in nfuncs:
- print('starting',funcs[i].__name__,'at:',ctime())
- print(funcs[i](n))
- print(funcs[i].__name__,'finished at:',ctime())
- print('\n***MULTIPLE THREADS')
- threads=[]
- for i in nfuncs:
- t=MyThread(funcs[i],(n,),funcs[i].__name__)
- threads.append(t)
- for i in nfuncs:
- threads[i].start()
- for i in nfuncs:
- threads[i].join()
- print(threads[i].getResult())
- print('All done.')
- if __name__=='__main__':
- test()
结果:
- >>>
- ***SINGLE THREAD
- starting fib at: Thu Aug 15 05:15:10 2013
- 233
- fib finished at: Thu Aug 15 05:15:13 2013
- starting fac at: Thu Aug 15 05:15:13 2013
- 479001600
- fac finished at: Thu Aug 15 05:15:14 2013
- starting sumF at: Thu Aug 15 05:15:14 2013
- 78
- sumF finished at: Thu Aug 15 05:15:15 2013
- ***MULTIPLE THREADS
- startingstartingstarting fibfacsumF at:at:at: Thu Aug 15 05:15:15 2013Thu Aug 15 05:15:15 2013Thu Aug 15 05:15:15 2013
- facsumF finished at:finished at: Thu Aug 15 05:15:16 2013Thu Aug 15 05:15:16 2013
- fib finished at: Thu Aug 15 05:15:17 2013
- 233
- 479001600
- 78
- All done.
queue模块进行线程间通信:
- import random
- from time import sleep
- from queue import Queue
- from myThread import MyThread
- def writeQ(queue):
- print('producting object for Q...')
- queue.put('xxx',1) #第一个参数为要写入Queue的数据,第二个参数为默认值,表示当Queue满的时候,会使线程暂停,直到空出一个位置
- print('size now',queue.qsize())
- def readQ(queue):
- val=queue.get(1) #这个参数为默认参数,表示当Queue为空时,线程暂停,直到有了一个数据
- print('consumed object from Q... size now',queue.qsize())
- def writer(queue,loops):
- for i in range(loops):
- writeQ(queue)
- sleep(random.randint(1,3))
- def reader(queue,loops):
- for i in range(loops):
- readQ(queue)
- sleep(random.randint(2,5))
- funcs=[writer,reader]
- nfuncs=range(len(funcs))
- def test():
- nloops=random.randint(2,5) #表示读与写的次数,读写次数相同
- q=Queue(32)
- threads=[]
- for i in nfuncs:
- t=MyThread(funcs[i],(q,nloops),funcs[i].__name__)
- threads.append(t)
- for i in nfuncs:
- threads[i].start()
- for i in nfuncs:
- threads[i].join()
- print('All done.')
- if __name__=='__main__':
- test()
结果:
- >>>
- startingstarting writerreader at:at: Thu Aug 15 05:57:00 2013Thu Aug 15 05:57:00 2013
- producting object for Q...
- size nowconsumed object from Q... size now 10 #这里不是10,而是一个1,一个0.1上writeQ()输出的,0是readQ()输出的
- producting object for Q...
- size nowconsumed object from Q... size now 10
- producting object for Q...
- size now 1
- writer finished at: Thu Aug 15 05:57:06 2013
- consumed object from Q... size now 0
- reader finished at: Thu Aug 15 05:57:10 2013
- All done.
0 0
- Python 多线程编程,thread
- Python学习笔记--多线程编程,thread
- python多线程编程(一)--thread模块
- python的多线程编程 --- thread模块
- python多线程编程(一)--thread模块
- python多线程编程之thread模块
- Python多线程编程之thread和threading
- [python] 专题八.多线程编程之thread和threading
- [python] 专题八.多线程编程之thread和threading
- Python系统编程(多线程-互斥锁-死锁-thread-threading)
- python多线程thread
- Python thread 多线程
- python多线程模块thread
- Python 多线程 Thread包
- Python 多线程 thread
- python--thread多线程总结
- Python多线程(Thread)
- Posix thread 多线程编程
- 记事本
- VS2010之禁止鼠标滑动控制大小
- Python 网络编程, socket
- Apidemo学习 WindowSurface
- hdu-1052Tian Ji -- The Horse Racing
- Python 多线程编程,thread
- Java 用函数调用求阶乘
- Python Tkinter制作GUI
- 题目1045:百鸡问题
- 算法之旅,直奔<algorithm>之十五 find
- XML Schema中targetNamespace概念
- How to create Oracle 11g R2 database manually in ASM?
- 25匹马,找出最快的3匹,但是只有5个赛道,每次比赛只能得到5匹马的速度排序,那么最少需要多少次比赛
- Tornado 与文件上传