C-程序设计-现代方法chp10-多线程.pptx
- 【下载声明】
1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
3. 本页资料《C-程序设计-现代方法chp10-多线程.pptx》由用户(三亚风情)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 程序设计 现代 方法 chp10 多线程
- 资源描述:
-
1、第十章 多线程第十章 多线程210.1 案例-顺序执行的局限10.1.1 案例的设计与实现 案例在程序做其它的事情的同时,在屏幕上显示一个实时时钟。设计和实现可以将“其它的事情”编码为一个函数,显示实时时钟编码为另一个函数,然后然而,如果按照常规的编码模式,那么就不可能有然后了,因为常规模式并不支持同时做多件事。第十章 多线程310.1 案例-类型带来的困扰10.1.1 案例的设计与实现size_t counter=0;template void count(T&v)+counter;/v未使用,可能导致编译警告 int main()linked_list l1,2,3,4,5,6;l.tra
2、verse(count);std:cout the list has counter elements std:endl;return 0;将实际的函数作为回调传递个traverse。使用回调函数有哪些问题呢?可能会因需编写太多的回调函数。程序员对代码的控制较弱。此例还用到了全局变量。第十章 多线程410.1 案例-类型带来的困扰10.1.2 案例问题分析同步 Synchronizationf()g();g()return;停 等第十章 多线程510.2 关键概念10.2.1 异步异步 Asynchronizationf()g();g()return;第十章 多线程610.2 关键概念10.2
3、.2 进程和线程进程(process)是正在运行的程序的一个实例。每一个进程都有它自己的地址空间,以及与运行相关的各种系统资源。多个进程可以并发执行。一个进程是可调度的,调度的工作由系统来完成。被调度的进程可以处于三种状态之一:运行态(running)、就绪态(ready)和阻塞态(blocked)。处于运行态的进程占据CPU资源。处于阻塞态的进程不占据CPU资源。第十章 多线程710.2 关键概念10.2.2 进程和线程线程(thread)是进程中的实体,是被系统单独调度的基本单位。除了运行时必备的资源外,线程一般不占有系统资源,但所有线程共享所属进程的资源。一个进程至少有一个线程。线程可以
4、由另一个线程创建,并可以所属进程中的其它线程并发执行。与进程一样,线程也有同样的三种状态:运行态、就绪态和阻塞态。第十章 多线程810.2 关键概念10.2.3 互斥和共享read dthread A:+dwrite dread dthread B:-dwrite dtime一种顺序读写操作read dthread A:+dwrite dread dthread B:-dwrite dtime另一种顺序的读写操作d=0d=-1d=0d=1数据竞争 Data race数据竞争必然带来不确定性问题。同一时间只能有一个线程独占共享数据访问权的排他性操作称为互斥(mutual exclusion)。第
5、十章 多线程910.2 关键概念10.2.4 锁和死锁要实现互斥,需要利用锁(lock)机制。常见的锁分为排他锁(exclusive lock)和共享锁(shared lock)。排他锁用于互斥操作。如果线程A对资源d成功地加上了排他锁,那么称A拥有这把锁。此种情况下,系统会拒绝其它所有加锁申请,并阻塞申请者,直到A解锁(unlock)为止。此后,被阻塞的线程(中的一个或一些)将得到调度。共享锁用于共享操作。如果线程A对资源d成功地加上了共享锁,那么其它所有的加共享锁的申请都会被接受;但加排他锁的申请将会被拒绝,直到A解锁为止。第十章 多线程1010.2 关键概念10.2.4 锁和死锁 通过仔
6、细安排程序的逻辑,同时利用锁机制,可以确保线程的竞争是可控制的,从而避免了数据的混乱。但是,如果安排不当,或者发生了不可控的意外,那么可能导致更加严重的问题:死锁(dead lock)。例如,线程A对d加上了排他锁,但在解锁之前A被杀死(kill)了,那么d上的锁将永久存在,其他的申请者将永远处于阻塞态得不到调度。这显然是不合理的。由于程序的逻辑可能很复杂,因此预防死锁的发生代价较高。常见的处理方法是允许死锁的发生,但系统会介入处理。例如:如果系统发现了死锁,并在预定时间内没有解锁,那么系统会强制解锁。第十章 多线程1110.3 C+的多线程库10.3.1 头文件 10.3.1.1 threa
7、d类 thread类是多线程程序设计的基础,最常用的是它的一个构造函数:template explicit thread(F&f,Args&.args);这是线程类的一个成员模板。其中,参数f是线程的执行样板,可以是任意满足条件的可调用对象,最常见的情况是一个函数;Args是可调用对象的模板参数包;args是传递给该可调用对象的参数。第十章 多线程1210.3 C+的多线程库10.3.1 头文件 10.3.1.1 thread类 thread类模板的实例化将会创建一个线程对象(thread object)。例如:void f()/线程的执行样板std:thread t(f);上述定义创建了一个
8、名为t的线程对象,它唯一代表了一个新的执行线程(thread of execution),该执行线程的执行路线以函数f为样板。第十章 多线程1310.3 C+的多线程库10.3.1 头文件 10.3.1.1 thread类 被线程对象代表的执行线程具有可结合(joinable)属性。一般情况下,新创建的线程要结合(join)到创建者线程中。这意味着,后者要等待前者的完成。这实际上是两个线程的同步。如果一个执行线程没有被任何线程对象代表,那么这个执行线程是分离的(detached)。用thread类模板的默认构造函数创建的新线程就是这样的。另外,新线程可以主动与创建者线程分离(detach)。第
9、十章 多线程1410.3 C+的多线程库10.3.1 头文件 10.3.1.1 thread类void f()/*做一件相对耗时的事情*/int main()std:thread t(f);return 0;这段代码将导致异常的发生。原因是:主线程(main)先于子线程t结束,而f具有joinable属性。解决办法是在创建线程t后,调用:t.join();这意味着主线程main要等待t执行完。另个一个办法是在创建线程t后,调用:t.detach();这意味子线程t可能没执行完就被主线程杀死。第十章 多线程1510.3 C+的多线程库10.3.1 头文件10.3.1.2 名字空间this_thr
10、ead yield()此函数的功能是为其它线程提供被调度的机会。如果一个线程可能会占据CPU资源太久,那么可以在其中调用此函数,给其它线程执行的机会。sleep_until(abs_time)调用此函数模板的线程会被阻塞,直到超时。超时时限是个绝对时间,由参数abs_time指定。sleep_for(rel_time)调用此函数模板的线程会被阻塞,直到超时。超时时限是个相对时间,由参数rel_time提供。第十章 多线程1610.3 C+的多线程库10.3.2 头文件 10.3.2.1 mutex类 有用的成员:lock()由线程发起,申请进行加互斥锁操作。一旦申请线程加锁成功,那么它将成为这
11、个锁的拥有者;否则,申请线程会被阻塞。在拥有者解锁之前,其它申请用同一个mutex对象加互斥锁的线程都会被阻塞。解锁后,被阻塞的线程会得到调度的机会。unlock()锁的拥有者发起此解锁操作。此后,原线程不再是该锁的拥有者。原则上讲,锁的拥有者必须在适当时候解锁,否则会造成死锁。mutex m;void print(int i)m.lock();cout i ;m.unlock();mutex m;void print(int i)lock_guard lock(m);cout i ;/lock_guard的析构函数自动解锁第十章 多线程1710.3 C+的多线程库10.3.3 头文件 一个线
展开阅读全文