操纵体系Lesson8 - 同步互斥机制和编程方法

打印 上一主题 下一主题

主题 1041|帖子 1041|积分 3123


忙等互斥与就寝叫醒

为相识决多个历程之间的操纵不会相互干扰,于是有了这两种操纵。


  • 忙等互斥:小时间事件适用
  • 就寝与叫醒:长时间事件适用
阻塞:就寝
忙等:自旋锁
内核中有些适合忙等,由于就寝需要维护就寝队列等结构,耗时长,有时不如忙等。


如何解决


克制多个历程同一时刻对共享资源进行读写


  • 共享资源包括:共享内存、共享文件等
   历程0-3G独立资源,3~4G共享内核,而文件资源等都是共享的
  设立临界区

临界区:将一块共享资源框起来,这段代码就叫临界区。
确保一个或多个历程不会在同一时间对同一共享资源(包括但不限于共享内存、共享文件等)进行读写操纵。这要求实现一种称为 互斥(Mutual Exclusion) 的机制,即当一个历程正在利用某共享资源时,其他历程必须被制止访问该资源。
为了正确高效操纵临界区资源,对临界区的锁操纵需要遵循以下四个原则:空闲让进、忙则等待、有限等待、让权等待

忙等互斥

为相识决互斥问题,下面列出了多种方法。
屏蔽停止

我直接把其他任务对CPU的打屏蔽了不就行了,就可以独占CPU了。
停止分为两种:
外部IO停止、时钟停止
恒久屏蔽停止,CPU无法接收IO消息,也无法被时间片打断,也就无法被其他任务调理,如果此时发生错误,CPU也接收不到停止,会导致死机。
实行方法:步伐一进入临界区就屏蔽停止,完成后恢复

可行性

历程进入临界区由谁决定?


  • 如果是用户历程,步伐员可决定,那黑客步伐怎么办?
  • 以是一样寻常不会给用户,内核来做

对单核处理体系上,最简朴

由于多核CPU实行屏蔽停止代码,只是针对本身一个CPU,而别的CPU不知道,以是利用TSL、XCHG指令,用来把整条数据线掐断。
以是说屏蔽停止一样寻常很短


锁变量

锁分两种:自旋锁和互斥锁
自旋锁


  • 忙等锁,不放弃CPU,轮询CPU,不断查询。
  • 适合小周期
互斥锁


  • 阻塞举动,一旦发现资源不可用,就寝,放弃CPU,等待被另外的步伐 段叫醒
  • 适合大周期

如果用int数据范例定义自旋锁:


  • 我们由上节课可知,从内存取变量分为三步:取出,操纵,写回
  • 如果在判断乐成后准备将锁置为1时时间片到了,那么锁照旧0,被另一个历程抢到然后进入资源区,两个人进入同一资源区,就会造成严峻后果。
以是说用软件根本对此(互斥)无能为力。
于是提出了原子变量实行期间无法打断,要么不开始,要么做完。

由于早期硬件跟不上,于是照旧借助软件,实现了:自旋锁
提供接口:
spin_lock();关停止,写入、读取数据
spin_unlock();开停止

现在:有专门的指令集来(TSL)对此操纵,特性:测试设置、比较交换。
而对于之前的接口,软间实现稳定,OS根据硬件是否支持硬件停止来决定是否翻译为TSL指令集。

严酷轮询法

单变量轮询:


  • 用历程号turn来规定谁能进入临界区;
  • 毛病:

    • 历程0的非临界任务很长,当历程1完成临界任务后将变量设为历程0的历程号后,很快实行完了非临界的任务,
    • 然而变量照旧历程0的历程号,历程1没办法访问临界区资源了,违背了空闲让进原则




Peterson算法

有两种:忍让型、自动自信型
问题代码:两个人相互忍让,造成死锁。


enter函数中:


  • 历程0先抢到时间片实行,将本身状态更新为感爱好,此时时间片结束;
  • 历程1也之开始实行这个代码段,也将本身的状态更新为感爱好;
  • 造成死锁,两人相互忍让。
解决方案


引入turn,等待条件改变:查抄对方是否想利用,且忍让轮到他


  • 首先将本身的状态改为感爱好;
  • 然后尝试忍让给另一个历程:

    • 如果对方历程不感爱好,我直接就能进入临界区访问资源;
    • 如果对方也感爱好,就会查抄忍让的这个turn轮到谁了,轮到谁,谁能访问,另一个轮询阻塞。

但是未遵循让权等待原则,由于当初设计的时间也没想到这方面。
自动自信型:谁先举手谁先发言。
  1. // 记录当前“轮到”哪个进程进入临界区
  2. int turn;
  3. // 记录每个进程是否有意愿进入临界区
  4. int interested[N];
  5. // 进程号为0或1的进程进入临界区的函数
  6. void enter_region(int process) {
  7. int other = 1 - process; // 计算另一个进程的编号
  8. // 标记本进程希望进入临界区
  9. interested[process] = TRUE;
  10. turn = process; // 尝试将turn设置为当前进程号
  11. // 等待条件:如果turn仍然指向当前进程且另一个进程仍有意愿进入
  12. while (turn == process && interested[other] == TRUE) {
  13. // 忙等待,直到条件不满足
  14. }
  15. }
  16. // 进程离开临界区的函数
  17. void leave_region(int process) {
  18. // 标记本进程已离开临界区
  19. interested[process] = FALSE;
  20. }
复制代码

TSL指令

从硬件方面锁定,会将总线锁定,其他所有CPU都无法访问,来解决多核问题.

   开释锁无需原子操纵
  XCHG也是雷同的指令,都是将之前的状态读出来并测试。
由于硬件指令提供,一个周期就做完了,能实现多CPU操纵

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

商道如狼道

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表