Python多线程编程

来源:互联网 发布:grpc java 编辑:程序博客网 时间:2024/05/16 06:51
  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
0 0