Python多线程编程
退出线程: 可以调用thread.exit(),sys.exit()或抛出一个SystemExit异常等,但不可以kill掉一个线程
Python提供的用于多线程编程的模块:thread,threading,Queue.
threading模块对象:
Thread, Lock, RLock, Condition, Event, Semaphore BoundedSemaphore, Timer
Thread对象的函数:
start(), run(), join(timeout = None), getName(), setName(name), isAlive, isDaemon(),setDaemon(daemonic)
用Thread类创建线程的三种方法:
* 创建一个Thread的实例,传给它一个函数
* 创建一个Thread的实例,传给它一个可调用的类对象
* 从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()
运行结果:
starting at: Tue Nov 4 12:59:46 2014
start loop start loop 01 at: at: Tue Nov 4 12:59:46 2014Tue Nov 4 12:59:46 2014
loop 1 done at: Tue Nov 4 12:59:48 2014
loop 0 done at: Tue Nov 4 12:59:50 2014
all Done at: Tue Nov 4 12:59:50 2014
###############################################################################################
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 main():
print('strarting 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__':
main()
运行结果:
strarting at: <built-in function ctime>
start loopstart loop 01 at: at: Tue Nov 4 14:30:49 2014Tue Nov 4 14:30:49 2014
loop 1 done at: Tue Nov 4 14:30:51 2014
loop 0 done at: Tue Nov 4 14:30:53 2014
all Done at: Tue Nov 4 14:30:53 2014
###########################################################################################
###createdb.py
import threading
from time import 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())
###mul.py
from createdb import MyThread
from time import ctime,sleep
def fib(x):
sleep(0.005)
if x < 2:
return 1
def fac(x):
sleep(0.1)
if x < 2:
return 1
return (x * fac(x - 1))
def sum(x):
sleep(0.1)
if x < 2:
return 1
funcs = [fib,fac,sum]
n = 12
def main():
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__':
main()
运行结果:
*** SINGLE THREAD
starting fib at: Wed Nov 5 01:16:46 2014
None
fib finished at: Wed Nov 5 01:16:46 2014
starting fac at: Wed Nov 5 01:16:46 2014
479001600
fac finished at: Wed Nov 5 01:16:48 2014
starting sum at: Wed Nov 5 01:16:48 2014
None
sum finished at: Wed Nov 5 01:16:48 2014
*** MULTIPLE THREADS
startingstartingstarting fibfacsum at:at:at: Wed Nov 5 01:16:48 2014Wed Nov 5 01:16:48 2014Wed Nov 5 01:16:48 2014
fib finished at: Wed Nov 5 01:16:48 2014
None
sum finished at: Wed Nov 5 01:16:48 2014
fac finished at: Wed Nov 5 01:16:49 2014
479001600
None
all done
###################################################################################################
除了各种同步对象和线程对象外,threading模块中的其他函数:
activeCount()
currentThread()
enumerate()
settrace(func): 为所有线程设置一个跟踪函数
setprofile(func): 为所有线程设置一个profile函数
###################################################################################################
利用Queue模块解决生产者——消费者问题
常用的Queue模块的属性:
Queue模块函数:
queue(size): 创建一个大小为size的Queue对象
Queue对象函数:
qsize(): 返回队列的大小(由于在返回的时候,队列可能会被其他线程修改,所以是近似值)
empty()
full()
put(item,block = 0): 如果block非0,函数会一致阻塞到队列中有空间为止。
get(block = 0): 同上
Queue模块可以用来进行线程间通讯,让各个线程之间共享数据。
from random import randint
from time import sleep
from queue import Queue
from createdb import MyThread
def writeQ(queue):
print('producing object for Q...',queue.put('xxx',1))
print('size now',queue.qsize())
def readQ(queue):
val = queue.get(1)
print('consumed object from Q... size now',queue.qsize())
def writer(queue,loops):
for i in range(loops):
writeQ(queue)
sleep(randint(1,3))
def reader(queue,loops):
for i in range(loops):
readQ(queue)
sleep(randint(2,5))
funcs = [writer,reader]
nfuncs = range(len(funcs))
def main():
nloops = 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__':
main()
运行结果:
startingstarting writerreader at:at: Wed Nov 5 01:39:44 2014Wed Nov 5 01:39:44 2014
producing object for Q...consumed object from Q... size now None0
size now 0
producing object for Q... None
size now 1
consumed object from Q... size now 0
producing object for Q... None
size now 1
producing object for Q... None
size now 2
consumed object from Q... size now 1
consumed object from Q... size now 0
writer finished at: Wed Nov 5 01:39:52 2014
reader finished at: Wed Nov 5 01:39:56 2014
all done