版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Python程序设计与应用第13章多线程编程13.1线程与进程13.2多线程编程13.3Python多进程编程
本章小结◎了解进程与线程的概念。◎掌握多线程编程的基本方法。◎掌握多进程编程的基本方法。在计算机多核的环境下,为了能充分地利用CPU以提高程序执行的效率,Python提供了两种常见的多任务编程方式,分别为进程和线程。本章将针对Python中与进程和线程相关的内容进行详细讲解。学习目标:13.1.1
进程进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体。
进程的特性可以大致概括为以下几个方面: 1.动态性:进程的实质是程序在多道程序系统中的一次执行过程,进程是
动态产生,动态消亡的; 2.并发性:任何进程都可以同其他进程一起并发执行; 3.独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和
调度的独立单位; 4.异步性:由于进程间的相互制约,使进程具有执行的间断性,即进程按
各自独立的、不可预知的速度向前推进; 5.结构特征:进程由程序、数据和进程控制块三部分组成。13.1线程与进程13.1.2
线程
线程是操作系统能够进行运算调度的最小单位(程序执行流的最小单元)。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。13.2.1Python多线程的特殊性Python多线程的特殊性,并非由Python语言本身产生,而是Python的一些解释器产生的问题。有些解释器为了保证线程安全而引入了GIL(全局解释器锁)。而由于GIL的存在,同一时间解释器只能解释一条字节码(bytecode)。 Python的解释器CPython就引入了GIL,而大多数运行Python的环境即为CPython,因此有时我们会说“Python的多线程并不是真正的多线程”。在其他一些Python解释器下,如JPython,没有GIL限制,其多线程即为真正的多线程。因此,不能讲这一缺陷总结为Python的语言特性,而是大多数运行Python的环境的特性。13.2
Python多线程编程13.2.2使用threading模块进行多线程编程Python自带模块threading用来实现多线程编程。在使用前,请先importthreading来导入threading模块。1.创建与运行线程
使用threading模块创建线程常见的方式有两种,一种是直接使用threading模块的Thread()方法创建并初始化一个线程对象,Thread常用的参数有target与args,target为线程调用的函数,args为该函数需要的参数,以元组的方式传递。实例化线程对象后,我们可以使用成员函数start()运行该线程13.2.2使用threading模块进行多线程编程Python自带模块threading用来实现多线程编程。在使用前,请先importthreading来导入threading模块。1.创建与运行线程
使用threading模块创建线程常见的方式有两种,一种是直接使用threading模块的Thread()方法创建并初始化一个线程对象,Thread常用的参数有target与args,target为线程调用的函数,args为该函数需要的参数,以元组的方式传递。实例化线程对象后,可以使用成员函数start()运行该线程。除了使用threading的Thread()方法返回线程实例外,还可以自定义线程类型并使其继承threading.Thread类,此时,需要在自定义类的__init__函数中运行Thread类的__init__函数并重写run方法作为线程执行的函数。再实例化自定义线程类型并使用start()方法运行线程13.2.2使用threading模块进行多线程编程2.使用join()函数阻塞线程
在某一线程中对已经开始的线程使用join()方法,可以阻塞当前线程,直到被join()的线程执行完后,被阻塞的线程才能继续执行。join()方法还可以传递参数设置超时时间,即当被join的线程如果过了这个时间还没有执行完,则当前线程不会再等待被join的线程而直接开始执行。3.守护线程
在Python中,主线程结束后,非守护线程仍会执行直到其结束;而守护线程则会在主线程结束后被终止。 Python中守护线程的创建非常简单,只需要在线程开始前调用想成对象的setDaemon(True)方法即可。13.2.2使用threading模块进行多线程编程4.线程安全与线程锁如果多个线程没有操作同一对象,是不会出现线程安全问题的。然而,真实的情况是我们往往需要在多个线程中访问同一对象,那么,我们应该如何访问才不会出现难以察觉的线程安全问题呢?这就是线程锁诞生的原因。
线程锁,即用于线程间访问控制的锁,当一个线程使用以线程锁加锁时,其他线程无法请求该线程锁,这些线程将会被阻塞,只有该线程锁被释放时,被阻塞的线程才能继续运行。13.2.2使用threading模块进行多线程编程(1)互斥锁
互斥锁是threading模块提供的最简单的线程锁。因为这种线程锁使用acquire()加锁、使用release()对解锁,所以被称为互斥锁。
互斥锁的使用非常简单,你可以在全局使用threading.Lock()实例化一个互斥锁,在子线程操作共享的对象前使用acquire()加锁,操作完成后使用release()解锁。互斥锁可以解决多线程操作同一资源时产生的线程安全问题,然而有时,互斥锁会导致另一种更难发现的线程安全问题产生:死锁。
死锁不是一种线程锁,而是错误地使用线程锁而导致的另一种线程安全问题。例如,当我们交叉请求锁时,即一个线程先请求A锁再请求B锁后释放B锁再释放A锁,另一线程先请求B锁再请求A锁后释放A锁再释放B锁,这两个线程并发时,如果线程1锁定了A锁后切换到线程2锁定了B锁,此时,线程1无法再请求B锁,线程2也无法请求A锁,形成交叉死锁。13.2.2使用threading模块进行多线程编程(2)递归锁
递归锁的使用方法与互斥锁基本相同,使用threading.RLock()实例化递归锁,并使用acquire()、release()请求、释放锁。与互斥锁不同的是,RLock允许在同一线程中多次请求锁而不会产生死锁问题。使用RLock时必须严格使执行的acquire()与release()成对出现。13.2.2使用threading模块进行多线程编程5.使用Condition同步线程
除了线程锁,threading模块还提供了状态类Condition来实现复杂的线程同步问题。使用Condition类时,同样需要创建Condition实例。Condition实例除了具有互斥锁的acquire()与release()方法实现加锁、释放锁外,还有wait()与notify()等方法。 Condition实例对于加解锁操作会维护一个锁定池。 wait()方法的作用是将已加锁的线程解锁并放入等待池并阻塞,等待其他线程的通知才能运行。这个方法只能对加锁的线程使用,否则会抛出异常。 notify()方法则是从等待池中取出一个线程并通知,被通知的线程将自动调用acquire()方法尝试获得锁定。这个方法有一点很重要,它不会释放线程的锁定,使用前线程必须已获得锁定,否则将抛出异常。13.2.2使用threading模块进行多线程编程6.使用Event实现线程间通信 Event类其实可以看做简化版的Condition类,它也能阻塞线程等待信号、发出信号恢复阻塞中的线程,但是Event类不提供线程锁的功能。
使用Event前同样需要实例化Event对象,Event实例内部维护一个布尔变量,表示线程运行的状态 1.isSet()方法用来返回内部的布尔变量值。 2.wait()方法将使该线程阻塞,直到其他线程调用set()方法。 3.set()方法将布尔变量置为True,并通知所有阻塞中的线程恢复运
行。 4.clear()方法会将内部布尔变量置为False。13.2.2使用threading模块进行多线程编程7.使用Timer定时器Timer类实际上是Thread类派生出的一个类。使用Timer一样需要实例化Timer对象,实例化时有三个重要的参数需要传递,第一个是启动延迟时间,第二个是启动调用的函数,第三个是函数参数(可以不设置);实例化之后,调用start()方法即可启动定时器。13.2.2使用threading模块进行多线程编程8.使用local线程局部字典为了方便的储存不同线程的数据,threading模块还提供了local类。local类可以为不同线程储存互不干扰的同名数据。在使用时,需要在主线程实例化local类,然后便可以动态的追加、修改它的属性,而且这些属性在不同线程之间即使同名也不互相干扰。13.3.1Python多进程编程特点
在介绍Python多线程编程时,我们了解了由于一些Python解释器的原因,很多时候Python并不能让多个线程真正地并行,降低了多核cpu的利用率。而Python多进程运行时,每个进程有自己独立的GIL,可以充分利用多核cpu的性能。13.3
Python多进程编程13.3.2使用multiprocessing模块进行多进程编程Python的自带模块multiprocessing提供了便捷的多进程开发功能,使用前请先导入模块:importmultiprocessing。multiprocessing模块提供的类使用方法与多线程编程时使用的threading模块很相似。创建与运行进程 multiprocessing模块的使用方式与threading很相似,在创建新进程时,同样有直接使用multiprocessing.Process()返回新进程对象与使用自定义类继承multiprocessing.Process两种方式。不过需要注意的是,在Windows下使用multiprocessing编写多进程程序是,要在主进程开始前使用if__name__=="__main__":判断当前进程是否为主进程,并调用multiprocessing.freeze_support()函数,使代码只有为主进程时才能执行,否则因为在Windows下Python子进程会自动import主进程中内容,导致未判断的主进程中代码在子进程中被死递归调用而出错。 Process与Thread相似,具有target与args参数,分别为该进程执行的函数与其对应的参数。实例化Process对象后,同样需要调用实例方法start()启动进程。13.3.2使用multiprocessing模块进行多进程编程使用join()函数阻塞进程
多进程编程中,同样可以使用对子进程使用join()方法来阻塞当前进程,使被join()的进程全部执行完毕后继续执行当前进程。守护进程
当主进程结束时,守护进程随之结束而非守护进程依旧继续执行。将进程设置为守护进程的方式与设置守护线程略有不同,设置守护进程需要将Process的实例的deamon属性修改为True。进程锁
与多线程安全问题类似,多进程程序同样有进程安全问题,例如在多进程读写文件时,如果处理方式不当就会产生进程安全问题。
为了解决进程安全问题,multiprocessing模块也提供了Lock(互斥锁)与RLock(递归锁)类,其用法与线程锁类似。13.3.2使用multiprocessing模块进行多进程编程使用Semaphore类控制资源同时访问数量
有些情况,我们需要限制同时执行的最大进程数,这时我们可以使用Semaphore类。Semaphore类实例化时可以设置最大同时访问资源的进程数,使用Semaphore的acquire()方法与release()方法来请求与释放Semaphore控制,只有当同时获取Semaphore的进程数小于设定的最大值时,请求才会成功,否则会阻塞到有一进程释放。使用Value与Array类在进程间共享变量
多进程Python程序运行时采用多GIL并行,因此多进程程序不能使用global关键字访问全局变量。为此,multiprocessing模块提供了Value类与Array类使变量可以在内存中共享(使用时,请注意进程安全问题)。Value类型和Array类型实例化时均需要两个参数,一个是共享变量的类型,另一个是共享变量的值。其中类型需要使用Typecode表示。13.3.2使用multiprocessing模块进行多进程编程使用Pipe在两进程间通信
有时我们需要将一个进程中的一些值传递给另一进程使用,这时,我们可以使用multiprocessing模块提供的Pipe类。Pipe类实例化时会返回管道
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 暑期防暑营:在降温中康健
- 护理服务礼仪的实践技巧
- 护理师资沟通中的沟通障碍分析
- 广东省惠州市惠阳区2024-2025学年七年级上学期1月期末历史试题
- 2026年中建国际ai面试题库及答案
- 外部财务合作机构管理自查报告
- 2026年安全生产风险分级管控清单编制与安全检查培训考核卷及答案
- 2026年听力康复教师考试题及答案
- 2026年小学体育教师考试题及答案
- 2026年档案安全应急演练方案及总结
- 篮球馆运营管理办法
- 2025河南新乡市卫滨区博涵小学招聘考试参考题库附答案解析
- (2025年标准)软件 技术协议书
- 义齿佩戴清洗存放课件
- 小学英语-三年级升四年级英语阅读理解专项(附答案)
- 2025年四川广安爱众股份有限公司对外招聘考试笔试试题(含答案)
- 煤生字第665号关于颁发《煤矿矿井机电设备完好标准》的通知
- 滚针美容治疗技术解析
- 血液透析上下机操作流程
- 《证券投资学》全套教学课件
- 2024-2025学年北师大版物理八年级上册月考模拟试卷(1-2章)(含答案)
评论
0/150
提交评论