Python多线程编程
1.目的:为了并行运行相互独立的子任务,大幅度提高整个任务的效率(异步任务、运算密集型任务)
UserRequestThread:负责读取用户的输入,可能是一个I/O信道。程序可能会创建多个线程,每个用户一个,请求会放在队列中。
RequestProcessor:一个负责从队列中获取并且处理请求的线程,为下面这种线程提供了输出
ReplyThread:负责把给用户的输出取出来,如果是网络应用程序就把结果发送出去,否则就会保存在本地文件系统或者数据库中。
每个线程都有自己明确的任务。
2.线程有开始,顺序执行和结束三个阶段
3.全局解释器锁(GIL):对Python虚拟机的访问由全局控制锁来控制,正是这个锁能保证同一时刻只有一个线程在运行,python虚拟机按照以下的方式来运行:
(1),设置GIL (2)切换一个线程去运行 (3)运行:a.指定数量的字节码的指令或者 b.线程主动让出控制
(4)把线程设置为休眠状态 (5)解锁GIL (6)重复以上
4.在python中使用线程:_thread和threading模块以及queue模块。其中_thread)和threading模块允许用户自己创建和管理线程。queue模块允许用户创建一个可以用于多线程之间共享数据的队列数据结构
注意:要避免使用_thread模块。
_thread.start_new_thread和exit
5.threading 模块
5.1Thread类:
用Thread类,可以用多种方法来创建线程:
a.创建一个Thread的实例,传给他一个函数
b.创建一个Thread的实例,创给它的一个科调用的类对象
c.从Thread派生出一个子类,创建一个这个子类的试验
函数; start(),run(),join():线程挂起,getName(),setName()
isAlive(),isDaemon(),setDeamon()
用法:threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
当所有的线程都创建后再一起调用start()函数启动,而不是创建一个启动一个。不用再去管理一堆锁,只要简单的对每个线程调用join()函数就可以了
例子:1.构建一个线程类
#-*- encoding:utf-8 -*- import threading from time import ctime class MyThread(threading.Thread): def __init__(self,func,args,name=''): threading.Thread.__init__(self) self.func=func self.args=args self.name=name def getResult(self): return self.res def run(self): print('starting',self.name,'at',ctime()) self.res=self.func(self.args[0],self.args[1]) ####此处需要修改 print(self.name,'finished at:',ctime())
1.几种递归的运算
from MyThread import MyThread from time import ctime,sleep def fib(x): sleep(0.005) if x<2: return 1 else: return (fib(x-2)+fib(x-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 return (x+sum(x-1)) funcs=[fib,fac,sum] n=12 def main(): nfunc=range(len(funcs)) print('*****SINGLE THREAD') for i in nfunc: print('starting',funcs[i].__name__,'at:',ctime()) print(funcs[i](n)) print(funcs[i].__name__,'finished at:',ctime()) print('******MULTIPLE THREADS') threads=[] for i in nfunc: t=MyThread(funcs[i],(n,),funcs[i].__name__) threads.append(t) for i in nfunc: threads[i].start() for i in nfunc: threads[i].join() print(threads[i].getResult()) print('All Done') if __name__=='__main__': main()
利用Queue模块解决生产者和消费者问题
from random import randint from time import sleep from queue import Queue from MyThread 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 write(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=[write,reader] nfunc=range(len(funcs)) def main(): nloops=randint(2,5) q=Queue(32) threads=[] for i in nfunc: t=MyThread(funcs[i],(q,nloops),funcs[i].__name__) threads.append(t) for i in nfunc: threads[i].start() for i in nfunc: threads[i].join() print('All Done') if __name__=='__main__': main()