Python多线程模块Threading用法示例小结
本文实例讲述了Python多线程模块Threading用法。分享给大家供大家参考,具体如下:
步入正题前,先准备下基本知识,线程与进程的概念。
相信作为一个测试人员,如果从理论概念上来说其两者的概念或者区别,估计只会一脸蒙蔽,这里就举个例子来说明下其中的相关概念。
平安夜刚过,你是吃到了苹果还是香蕉呢。。。其实当你用手去接下对方苹果的时候,你的手臂就可以比喻成进程,你的五个手指就可以比喻成线程,所以很明显,线程可以说是进程的细化,没有进程就不会有线程。
这里还是说下必要的概念:
进程
是操作系统中当前程序的一次执行。要知道拥有单个CPU的电脑,在严格意义上,一个时间点上操作系统只能进行同一个工作命令。由于计算机的运行速度快,在工作时可以运行一会A代码,运行一会B代码,交错运行,由于运算速度快,所以一般看来它好像可以同时进行多个程序--这就是多进程。
线程
线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位,这里的单位指运行中的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程。线程还可以自己创建、撤销和切换。就像拿苹果,如果一根手指可以办到,那它就是单线程,如果需要多根手指,那就是多线程。
进程和线程的区别
(1)进程是资源的分配和调度的一个独立单元,而线程是CPU调度的基本单元
(2)同一个进程中可以包括多个线程,并且线程共享整个进程的资源(寄存器、堆栈、上下文),一个进程至少包括一个线程。
(3)进程结束后它拥有的所有线程都将销毁,而线程的结束不会影响同个进程中的其他线程的结束
(4)线程是轻量级的进程,它的创建和销毁所需要的时间比进程小很多,所有操作系统中的执行功能都是创建线程去完成的
(5)线程中执行时一般都要进行同步和互斥,因为他们共享同一进程的所有资源(资源竞争)
(6)线程有自己的私有属性TCB,线程id,寄存器、硬件上下文,而进程也有自己的私有属性进程控制块PCB,这些私有属性是不被共享的,用来标示一个进程或一个线程的标志
子进程与子线程的区别
进程和线程的区别在于粒度不同,进程之间的变量(或者说是内存)是不能直接互相访问的,而线程可以,线程一定会依附在某一个进程上执行.我举个例子,你在Windows下开一个IE浏览器,这个IE浏览器是一个进程.你用浏览器去打开一个pdf,IE就去调用Acrobat去打开,这时Acrobat是一个独立的进程,就是IE的子进程.而IE自己本身同时用同一个进程开了2个网页,并且同时在跑两个网页上的脚本,这两个网页的执行就是IE自己通过两个线程实现的.值得注意的是,线程仍然是IE的内容,而子进程Acrobat严格来说就不属于IE了,是另外一个程序,之所以是IE的子进程,只是受IE调用而启动的而已。
这里大家可能会疑惑,进程分配内存空间的依据是啥?其实进程建立,系统会为其分配虚拟地址空间4GB(在32位系统中),具体分配情况要取决于该包含的所有可执行模块或dll模块的代码和数据,还包含动态内存分配的空间(如线程中堆栈的分配)
好了,上面介绍了基本的线程及进程的概念,接下来可以开始正题了,这里主要总结下python内的Threading模块
python多线程之Threading
单线程
额,这个忽略吧。。。操作系统单任务的处理,排好队,一个一个来就是单线程。
多线程
多线程Threading一般可以通过两种渠道来实现:一种是通过继承Thread类,重写它的run方法;另一种是创建一个threading.Thread对象,在它的初始化函数(__init__)中将可调用对象作为参数传入,本质上来讲,两种方式一样。
来一发实例:
#-*-coding:utf-8-*- importthreading importtime #方式二是方式一的具体,方式一为类构造,方式二为方法实例构造,其实本质都是一样,都是调用threading.Thread模块 #方式一 count=0 classCounter(threading.Thread): def__init__(self,lock,threadName): #注意:一定要显式的调用父类的初始化函数,这里可以指定生成的线程名,可以是*args、**kwargs #def__init__(self,group=None,target=None,name=None,args=(),kwargs={}),其中group是预留的,将来用于扩展 super(Counter,self).__init__(name=threadName) self.lock=lock defrun(self): globalcount self.lock.acquire() foriinrange(100): count=count+1 self.lock.release() #方式二 lockA=threading.Lock() lockB=threading.Lock() rLock=threading.RLock() condt=threading.Condition() event=threading.Event() defadd(lockA): globalcount #定义当前资源只能单线程访问,锁住后完成资源调用一定要释放锁,不然会造成死锁状态,甚至程序崩溃 lockA.acquire() foriinrange(1000): count=count+1 #资源调用完毕,释放锁 lockA.release() defaddRunner(): foriinrange(2): th=threading.Thread(target=rloc,args=(rLock,)) #开启线程,从此刻起,多线程开始,主线程继续前行 th.start() #调用Thread.join[timeout]将会使主调线程堵塞,直到被调用线程运行结束或超时。参数timeout是一个数值类型,表示超时时间 th.join() print'-----%sisstart-----'%th.getName() print"over" #RLock允许在同一线程中被多次acquire,避免单线程出现思索情况 defrloc(rLock): rLock.acquire() foriinrange(2): rLock.acquire() printi, rLock.release() rLock.release() print"over!" defrlocRun(): foriinrange(2): th=threading.Thread(target=rloc,args=(rLock,)) th.start() print'-----%sisstart-----'%th.getName() print"over" #现在出现复杂的场景,多个线程需要调用多个共同的资源,此时就需要threading.Condition出马,加入简单的说就是A搞完了A的事 #,就发广播说明自己搞定了,其它人可以进来了,B同理。 defcond(cond): #适合那种主动休眠,被动唤醒的场景 cond.acquire() globalcount foriinrange(1000): count=count+1 #唤醒一个挂起的线程(如果存在挂起的线程),提醒当前的挂起的线程看看其它的锁开了没有,如果开了就搞其他的事。 #注意:notify()方法不会释放所占用的琐。 cond.notify() #wait方法释放内部所占用的琐,同时线程被挂起,直至接收到通知被唤醒或超时 cond.wait(5) #相信大家应该看出问题来了,最后一个线程咋办列,没人唤醒啊,这个时候应该做过一个判断 cond.release() print"over!" defcondRun(): globalcondt foriinrange(0,3): th=threading.Thread(target=cond,args=(condt,)) th.start() print'-----%sisstart-----'%th.getName() print"over" #此时可能会有一点问题,就是线程的同步(并发)问题怎么解决呢?此时threading.Event出马 defeven(n,event): whilenotevent.isSet(): print'Thread%sisready'%n time.sleep(1) #同condition一样,挂起该线程,等待set开关 event.wait() whileevent.isSet(): print'Thread%sisrunning'%n time.sleep(1) defevenRun(): foriinrange(0,2): th=threading.Thread(target=even,args=(i,event)) th.start() time.sleep(3) print'-----eventisset-----' event.set() time.sleep(3) print'-----eventisclear-----' event.clear() if__name__=="__main__": Counter(lockA,"thread1").start() addRunner() rlocRun() condRun() evenRun()
更多关于Python相关内容感兴趣的读者可查看本站专题:《Python进程与线程操作技巧总结》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》、《Python+MySQL数据库程序设计入门教程》及《Python常见数据库操作技巧汇总》
希望本文所述对大家Python程序设计有所帮助。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。