- 1、本文档共65页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
第五讲 Linux多线程
Linux多线程 李杰聪 世界不是串行的 真实世界中很多事情都是同时发生的,而不是按次序发生。 随着软硬件的发展计算机也进入了并行时代。 程序员也应该做好并行程序设计的准备。 处理器发展历史回顾 90年代——增大指令的并行发射能力,超标量处理器。 90年代末期至21世纪初——提高主频 21世纪——超线程,多核技术出现,主频不再决定CPU性能。 处理器种类 通用处理器:intel, amd生产。 网络处理器:摩托罗拉, powerpc ,cavium 嵌入式处理器:TI(高通),ARM 图像处理器:nvida 银行卡 银行卡 正确执行(账户归零) Pos1 ? ① Pos1 ? ② Pos2 ? ① Pos2 ? ④ Pos1 ? ③ 并发的几个概念 竞争(race condition):程序执行的结果或者输出取决于某一段代码的执行次序,次序不同结果不同。 竞争是不确定的,偶发性较强。 导致系统异常,数据被破坏。 难以重现,调试,发现竞争。 加入调试代码时,竞争会消失?! 银行卡存在数据竞争。 并发的几个概念 原子性(atomic):是系统中最小的一个操作集合。 银行卡例子中,更新账户余额的操作集合需要时一个原子操作。也即 ① ②是一个原子操作,否则引入竞争。导致程序运行结果不确定。 也可把① ② ③ ④作为原子操作,但会降低程序性能。 对竞争的判断同时也是对原子操作范围的界定。 程序设计中,竞争区域判断比想象中要困难很多。 哲学家问题 有5个哲学家围坐在一张圆桌上。 每相邻两个哲学家之间有一只筷子。 哲学家除了思考就是吃。 当哲学家饿时,他就先拿起作手边的筷子然后再拿右手边的筷子 。当有两只筷子时,哲学家开始吃饭,否则一直等待另外一只筷子。 哲学家吃晚饭后,放下筷子,继续思考。 并发中的问题 死锁 (deadlock):两个或者以上的线程互相等待,导致整个系统无法向前推进。 例如:5个哲学家同时拿起自己左手边的筷子,然后等待右手边的筷子。由于所有筷子均被占有,导致没有一个哲学家能进食。 并发中的问题 活锁(livelock):两个或者以上的线程会不断的执行,不断的改变状态,但整个系统却不朝着最终目的前进。 活锁一般为了解决死锁引入的。死锁的线程只会等待,不会改变状态。活锁会改变执行状态,但不会朝着最终目标前进。 为了解决哲学家的死锁问题。我们规定:如果哲学家无法拿到右手边的筷子,那么他必须放下他左手边的筷子。等待一会儿再去尝试拿筷子。 举例:5个哲学同时拿起左手边筷子, 发现右手边的筷子没有,又同时放下左手上的筷子,如此往复 并发中的问题 饥饿、饿死(starvation):某些线程永远无法得到执行的机会。 举例:某一哲学家,每次去拿筷子时,左手或者右手边的筷子被拿走,该哲学家只能一直“饿肚子”。 公平性(fairness):有些线程得到的执行机会多, 有些线程得到的执行机会少。 举例:哲学家在拿筷子时,有些哲学家拿到筷子的可能性可能比其它哲学家大。比如那些好吃懒做,整天尝试去拿筷子的哲学家。 多线程概念 进程是资源分配的对象,时间片内存等。 线程是使用资源的实体,一个进程中的多个线程共享内存,全局变量, 文件描述符等。 线程有独立的栈和寄存器 线程的优缺点 优点: 上下文切换快 共享数据容易 创建线程速度快 缺点 内存共享会导致互相干扰 一个线程崩溃会导致整个进程崩溃 用户级线程 线程可以在用户层或者内核层提供 在用户层实现线程意味着内核并不知道线程的存在。 用户层线程库会实现线程的创建、删除、调度。 用户层的线程创建比较快 当某个线程要使用内核时,其余线程都会被挂起。 内核级线程 内核直接支持线程 线程的创建、删除和调度都有内核来做。 一个线程等待I/O阻塞时,其余线程可以继续运行。 创建等操作要进出内核,速度会慢些。 目前流行的操作系统都支持内核级线程。 多线程模型 内核线程和用户线程的对应关系 一个内核线程对应n个用户线程(用户级线程) 一个内核线程对应一个用户线程(内核级线程) 用户级线程 内核级线程 多线程中的fork 在linux系统当一个拥有多线程的进程调用fork时,子进程只会有一个线程! 多线程中的信号 在linux系统中信号是用来通知进程特殊事件发生了 多线程中有哪个线程来处理呢? 信号会被递送给恰当的线程,比如SIGILL非法指令。 信号会被递送给进程中任意的线程处理。 在多线程环境我们一般指定一个线程专门处理信号,其余线程全部屏蔽信号处理。 线程池 在程序设计中,并不是来一个任务/请求就创建一个线程,执行完毕线程退出。 程序初始化时创建一个线程池,线程池中有n个线程。 当一个请求来时,从线程池中取一个线程,完成请求后线程再放回线程池。 节省了频繁创
文档评论(0)