文章目录

  • 10.1 信号量概念
  • 10.2 信号量的使用
  • 10.3 管程
    • 10.4 经典同步问题
  • 10.5 练习题

10.1 信号量概念

信号量(Semaphore)是另一种临界区的保护机制,它是操作系统提供的一种协调共享资源访问的方法。
它将资源纳入全局考虑,从操作系统的层面对资源进行宏观的调配。

这个机制由Dijkstra在20世纪60年代提出,是早期操作系统的主要同步机制。

信号量Semphore中的整数sem就是这个系统资源剩余量。申请时减少,释放时增加即可,没有时等待分配,所以先进先出
实现的结构和lock很像。

具体的实现接口为P()V(),分别是荷兰语(?)增加prolagg和减少verhoog的缩写。

信号量的实现(其中sem是剩余资源)

class Semaphore {int sem;WaitQueue q;
}Semaphore::P(){sem--;if (sem < 0) {Add thread t to q;block(p);}
}
Semaphore::V(){sem++;if (sem <= 0) { // 说明队列中有线程在等待Remove a thread t from q;Wakeup(t);}
}

如果弄懂了clock的机制,从上面的代码中信号量应当是非常好理解的,这个机制拥有如下的特征:

  • sem是由操作系统全局保护的整数变量,信号量的相关操作是原子操作。不像软件方法,相关操作不会被打断。
  • P()可能阻塞,V()不会阻塞
  • 通常假定信号量是“公平的”:
    • 线程不会无限地阻塞在P()操作
    • 假定信号量等待按先进先出

10.2 信号量的使用

信号量可分为二进制信号量(资源数目为0或1)和资源信号量(资源数目为任何非负值),基于其一可以实现另一个。

信号量可以用于实现临界区的互斥访问和线程间的条件同步

用信号量实现临界区的互斥访问,示例如下:

mutex = new Semaphore(1);mutex->P();
Critical Section;
mutex->V();

必须成对使用P()操作和V()操作,不能颠倒、重复或遗漏

利用P和V配对的性质,可以将P和V分开,从而实现条件同步。
在如下图的线程A中,如果调用P,那么信号量将变为-1,进入等待状态(这是信号量设计中很精髓的FIFO)。线程B调用V之后,信号量变为0,这时A重新开始运行,从而就实现了两个线程的同步。

生产者-消费者问题

  • 任何时候只能有一个线程操作缓冲区(互斥访问)
  • 缓冲区空时,消费者必须等待生产者(条件同步)
  • 缓冲区满时,生产者必须等待消费者(条件同步)

用信号量描述在这个问题当中的约束:

  • 二进制信号量mutex表示I/O是否被占用,初始化为1
  • 资源信号量fullBuffers表示当前占满的缓冲区数量,用于限制读出,初始化为0
  • 资源信号量emptyBuffers表示当前为空的缓冲区数量,用于限制写入

伪代码如下:

class BoundedBuffer{mutex = new Semaphore(1);fullBuffers = new Semaphore(0);emptyBuffers = new Semaphore(n);
}

其生产、消费两个过程相互对称,

BoundedBuffer::Deposit(c){emptyBuffers->P();//条件同步mutex->P();    //互斥访问Add c to buffer; //核心操作mutex->V();    //互斥访问fullBuffers->V();//条件同步
}
BoundedBuffer::Withdraw(c){fullBuffers->P();//条件同步mutex->P();    //互斥访问Add c to buffer; //核心操作mutex->V();    //互斥访问emptyBuffers->V();//条件同步
}

使用信号量的困难在于:

  • 读/开发都比较困难
  • 容易出错
  • 不能系统性地解决死锁问题

10.3 管程

管程是一种更为现代的实现互斥访问的方法。与临界区相比,管程有更好的封装,如果设计得当,则处理各种问题时,使用将极为便捷。但我感觉这可能是迄今为止最难以理解的一节。

类似我们要为临界区实现提供lock和semaphore两种工具类,对于管程,我们还要实现一个条件变量condition类。

管程通过使用条件变量提供对同步的支持,这些条件变量包含在管程中,并且只有管程才能访问

与信号量的一个最为重要的不同在于,使用条件变量时,如果进入等待状态,还能暂时放弃管程的互斥访问等待事件出现时恢复,从而并行进行其他操作,而不是简单地像对临界区那样“固守”。
这一点是使用了条件变量的好处,可以看到中途释放了lock。

用管程解决生产者-消费者问题

通过良好的设计封装,可以降低使用过程的使用难度。
具体使用情景下,Deposit和Remove都只需要简单的对外接口,但有着有效的互斥访问机制。

管程中的条件变量按照不同的释放处理方式分为两种:

  • 内部的线程优先执行(Hoare)
  • 正占用管程处于执行状态的线程优先执行(Hansen)

具体的实现,按照老师的说法是将管程中的while非常关键,它保证能在管程T2退出之后再恢复T1的管程执行,这样实现的Hansen管程,切换次数较少,实际使用效率更高。

Hoare管程只需要将while改成if。正确性更容易说明,更适合理论分析和教学。(srds我还是不懂

10.4 经典同步问题

哲学家就餐问题(五人和五个叉子交替围圈,每个人有思考吃饭两个状态,吃饭需要左右两只叉子)
要防止死锁,又要有尽可能多的人吃到。
一个合理的思路是,避免大家完全用同样的手先发。

#define N 5
semaphore fork[5];
void philosopher(int i){while (true){think();if (i % 2){p(fork[i]);p(fork[(i+1)%N]);} else {p(fork[(i+1)%N]);p(fork[i]);}eat();V(fork[i]); // 释放不阻塞,因而不用使用分支区别对待V(fork[(i+1)%N]);}
}

更详细的解析,见https://blog.csdn.net/theLostLamb/article/details/80741319

读者-写者问题
正是之前所提到的同步互斥的一个抽象版本。要求读读不互斥,读写和写写都互斥。管程可以简化同步问题的实现方法。

这里略去,可见https://blog.csdn.net/hhypractise/article/details/107150434

10.5 练习题

一个进程由阻塞队列进入就绪队列,可能发生了哪种情况_________(A)

  • A. 一个进程释放一种资源
  • B. 系统新创建了一个进程
  • C. 一个进程从就绪队列进入阻塞队列
  • D. 一个在阻塞队列中的进程被系统取消了

如果有5个进程共享同一程序段,每次允许3个进程进入该程序段,若用PV操作作为同步机制则信号量S为-1时表示什么_________(C)

  • A. 有四个进程进入了该程序段
  • B. 有一个进程在等待
  • C. 有三个进程进入了程序段,有一个进程在等待
  • D. 有一个进程进入了该程序段,其余四个进程在等待

管程的主要特点有__________(ABD)

  • A. 局部数据变量只能被管程的过程访问
  • B. 一个进程通过调用管程的一个过程进入管程
  • C. 不会出现死锁
  • D. 在任何时候,只能有一个进程在管程中执行

清华向勇《操作系统》学习笔记10:信号量与管程相关推荐

  1. 哈工大操作系统学习笔记十——信号量与死锁

    哈工大os学习笔记十(信号量与死锁) 文章目录 哈工大os学习笔记十(信号量与死锁) 一. 信号量临界区保护 1.为什么要保护信号量 2.临界区 3.保护信号量的方法 3.1 轮换法 3.2 标记法 ...

  2. 学习笔记--RTOS信号量

    学习笔记–RTOS信号量 本文基于正点原子RTOS开发指南,笔记自用,获取详细信息请关注正点原子官方账号 简介:信号量是一种解决同步问题的机制,可以实现对共享资源的有序访问.和linux中的信号量差不 ...

  3. UC/OS III操作系统学习笔记

    UCOS操作系统学习笔记 1.UCOSIII任务 1.1任务管理 1.2 任务创建和删除.挂起和恢复 1.3 系统内部任务 2.UCOSIII中断和时间管理 2.1 中断管理 2.2 时间管理 3.U ...

  4. Linux操作系统学习笔记【入门必备】

    Linux操作系统学习笔记[入门必备] 文章目录 Linux操作系统学习笔记[入门必备] 1.Linux入门 2.Linux目录结构 3.远程登录 3.1 远程登录Linux-Xshell5 3.2 ...

  5. ROS机器人操作系统学习笔记(三)ROS通信架构

    ROS机器人操作系统学习笔记(三)ROS通信架构 ROS的通信架构是ROS的灵魂,也是整个ROS正常运行的关键所在.ROS通信架构包括各种数据的处理,进程的运行,消息的传递等等.本章主要介绍了通信架构 ...

  6. Python学习笔记--10.Django框架快速入门之后台管理admin(书籍管理系统)

    Python学习笔记--10.Django框架快速入门之后台管理 一.Django框架介绍 二.创建第一个Django项目 三.应用的创建和使用 四.项目的数据库模型 ORM对象关系映射 sqlite ...

  7. thinkphp学习笔记10—看不懂的路由规则

    原文:thinkphp学习笔记10-看不懂的路由规则 路由这部分貌似在实际工作中没有怎么设计过,只是在用默认的设置,在手册里面看到部分,艰涩难懂. 1.路由定义 要使用路由功能需要支持PATH_INF ...

  8. SpringMVC:学习笔记(10)——整合Ckeditor且实现图片上传

    SpringMVC:学习笔记(10)--整合Ckeditor且实现图片上传 配置CKEDITOR 精简文件 解压之后可以看到ckeditor/lang下面有很多语言的js,如果不需要那么多种语言的,可 ...

  9. freeRtos学习笔记 (7)信号量

    freeRtos学习笔记 freeRtos信号量 信号量种类 信号量分为四种:二值信号量,互斥信号量,计数信号量和递归互斥信号量,其中计数信号量用于管理系统多个共享资源,用计数值表示可用资源数目;二值 ...

  10. springmvc学习笔记(10)-springmvc注解开发之商品改动功能

    springmvc学习笔记(10)-springmvc注解开发之商品改动功能 springmvc学习笔记(10)-springmvc注解开发之商品改动功能 标签: springmvc springmv ...

最新文章

  1. Android后台保活实践总结:即时通讯应用无法根治的“顽疾”
  2. gradle各版本下载地址
  3. 二分法——leetcode35. 搜索插入位置
  4. 紫书搜索 习题7-4 UVA - 818 Cutting Chains 暴力+dfs判环+位运算
  5. erp无线架设服务器,erp数据库架设在云服务器上
  6. C++ 智能指针简介
  7. .NET Core Linux环境搭建(CentOS 7)
  8. POI导出换行和水平居中
  9. 输入一个正整数n(n<360),输出n度的正弦余弦值
  10. android短信验证码登录,Android注册登录实时自动获取短信验证码
  11. macOS Monterey 12.1 (21C52) 正式版 ISO、IPSW、PKG 下载
  12. h5底部输入框被键盘遮挡_搜遍整个谷歌, 只有我是在认真解决安卓端hybrid app键盘遮挡输入框的问题...
  13. 【邢不行|量化小讲堂系列06-Python量化入门】极简方法将日线数据转为周线、月线或其他周期
  14. 自己做量化交易软件(10)通通量化AI框架的数据获取与格式
  15. java使用阿里云发送通知短信
  16. 使用JTAG Flash Programmer烧写Flash
  17. 新网域名添加AAAA记录
  18. 北斗GPS定位系统原理
  19. Kotlin 旅途篇(一)
  20. 【亲测有效】如何解决Hadoop运行jar包 报错Exception in thread “main“ java.lang.ClassNotFoundException: /input

热门文章

  1. 计算机论文基础与发展实践报告,大学生计算机基础论文摘要_计算机实践基础论文3000_计算机论文3000字...
  2. 题目 1870: 统计字符数
  3. 使用PHP添加圆形头像
  4. 手撕伪装“京东金条”客服诈骗
  5. php怎么改成java,求大神帮忙把php的改成java谢谢
  6. 火星人敏捷开发手册视频培训上线了!
  7. 二叉树的前序遍历,二叉树的中序遍历,二叉树的后序遍历,二叉树的层序遍历
  8. 【报告分享】运营必备11大数据分析模型-易观分析(附下载)
  9. 并行算法笔记(二)——并行算法设计
  10. 信息学奥赛一本通 1011:甲流疫情死亡率