在实现多线程互斥访问共享变量中,除了使用互斥锁之外,还可以使用信号量,当然信号量不仅仅能够实现互斥,还能够实现同步问题。

信号量的历史这里就不写了,信号量的分类也有几种,这里仅仅讨论一下记录型信号量。

记录型信号量是一个与队列有关的整型变量,大白话来讲,记录型信号量是一种数据结构,除了一个整型变量外,还有一个队列,记录型信号量定义如下:

type semaphore=recordvalue:integer; # 整形变量Q: list of process;  # 队列end

记录型信号量仅仅能够被P原语和V原语进行操作,P原语申请资源,V原语释放资源,那P原语和V原语是如何实现原子性操作的?

在深入探索P原语和V原语之前,我们知道了可以利用Test and Set指令(swap指令)实现互斥锁的acquire方法(点这里):

# Test and Set(python),原子性操作
def TS(lock):if lock == 0:lock = 1return Truereturn False
# 利用TS指令实现acquire方法
def acquire():while not TS(lock):pass // 忙等状态

可以看到,在锁处于open状态时,TS指令保证了只能有一个线程能够改变锁的状态,使锁处于locked状态,在由locked改变为open状态之前,其他来获取锁的线程只能while循环,不能够获得锁。

接下来我们看一看记录型信号量P原语与V原语的伪代码:

# 定义记录型信号量
​
type semaphore=recordvalue:integer; # 整形变量T: list of thread;   # 队列end# P原语
P(s):s.value = s.value - 1 # if s.value < 0then beginblock t;insert t into Tend;
​
# V原语
V(s):s.value = s.value + 1if s.value <= 0then beginwakeup the first T;remove the P from Tend
​

为了能够更直观的理解P操作和V操作的实现逻辑,可以将上述代码转换为下述流程图:

由上述流程图,我们可以看到

信号量的P原语,需要完成两件事:

  1. 当访问value时,将value减1
  2. 当资源被消耗完时,需要将请求资源的当前线程推入阻塞队列

信号量的V原语,需要完成两件事:

  1. 当访问value时,需要将value加1
  2. 当阻塞队列中有阻塞线程时,需要唤醒一个线程

接下来就是重点了,如何利用操作系统的TS指令实现信号量P原语、V原语,使这两个原语具有原子性?

我们可以看到,在使用信号量的时候,value作为共享资源,那就会出现如下几种争抢临界资源的情况:

  • 多个线程的P原语之间
  • 多个线程之间的P、V原语
  • 多个线程之间的V原语

所以在P、V原语内要有互斥控制,保护临界资源不被同时访问到,避免数据不一致的情况,这里需要一个变量来保护临界资源。定义一个mutex,用来保护value,因为有一把互斥锁,获取时都可能会产生忙等现象,除了上述提到的队列T,应该还有一个队列M。

所以现在信号量的内部结构变为:

type semaphore=recordvalue:integerT:list of Thread wait for valueM:list of Thread wait for internal mutexmutex:boolean = 0 # 互斥锁

P原语:

def acquire():while not TS(lock): # 获取mutex,用来互斥访问s.valueblock tinsert t into Ms.value = s.value - 1if s.value < 0: # 表示资源已经用完了lock = 0 # 释放互斥锁,其他的线程或者acquire方法或者release方法可以来访问value了wakup the first t from M # 唤醒M队列中的线程remove the t from Mblock t         insert t into Telse:lock = 0wakeup the first t from Mremove the t from M

V原语:

def release():while not TS(lock):block t insert t into Ms.value = s.value + 1if s.value <= 0: # 表明阻塞队列中还有待唤醒的线程wakeup the first t from T remove t from Tlock = 0 # 释放锁wakeup the first t from Mremove the t from M

以上就是个人对记录型信号量的理解,以及尝试结合系统的TS指令实现了一下信号量的P原语与V原语,如果您看到了,有理解的不对的地方,欢迎指正,也欢迎与各位进行交流。

参考:

  1. http://faculty.salina.k-state.edu/tim/ossg/IPC_sync/ts.html#implementing-semaphores-with-test-and-set
  2. 图书/计算机操作系统原理与设计
  3. https://www.icourse163.org/course/UESTC-1205790811
  4. https://zhuanlan.zhihu.com/p/136173505

ts 变量后面加问号或者叹号_关于记录型信号量与TS指令的理解相关推荐

  1. 逗号,句号。问号?叹号!顿号、冒号:人名分隔·

    / \ [].,?!@"':;-+-*/=~()[]{}<>|_\^`%$· 富文本编辑器 ,.?!.::. ** ,.?!.::.** 逗号,句号.问号?叹号!顿号.冒号:人名 ...

  2. 技术文章里那么多的问号与叹号

    引言 记得之前写的一些技术文章,部分使用了[第一人称]的写法,也就是带着个人情感,让读者一起去探索.一起去分享感受那些表面看起来[毫无波澜],实则[别有洞天]的技术与观点. 很多人反感里面过多的[问号 ...

  3. js变量后面加问号是什么_js没那么简单(1)-- 执行上下文

    前言 我为什么写这个文章?也许换个耳熟能详的话题会有更多人看吧.之前发了个tls感觉阅读量不行. 要讲ecma语法吗?我觉得还是不了吧,毕竟这些繁琐,枯燥,而且门槛低. 那讲什么好?讲一点我自己觉得大 ...

  4. js变量后面加问号是什么_JS变量生命周期:为什么 let 没有被提升

    译者:前端小智 原文:https://dmitripavlutin.com/variables-lifecycle-and-why-let-is-not-hoisted/ 为了保证的可读性,本文采用意 ...

  5. 重启手机出现机器人加一个叹号_解决win10上不了网出现红叉,网卡驱动异常代码56的问题...

    问题: 昨天周一早上来到公司,发现跳闸停电了...半个钟之后老哥修好了,打开电脑一看 居然上不了网了,刚开始只是出现个黄色感叹号,但是搜索识别不了任何WiFi 瞎点的我看到了这个,于是乎我点了进去网络 ...

  6. 重启手机出现机器人加一个叹号_印度科幻脑洞高能!《宝莱坞机器人2.0》内地定档...

    1905电影网讯印度脑洞"神片"<宝莱坞机器人2.0:重生归来>释出定档海报,并宣称中国内地定档9月6日. <宝莱坞机器人2.0>讲述了,在印度某市,所有人 ...

  7. 一句话的结束!句号问号叹号

    标点符号分为点号和标号两大类. 点号的作用在于断点,主要表示说话时的停顿.句末点号有句号.叹号.问号3种, 表示句末的停顿(也就是表示一句话结束),陈述句用句号,疑问句用问号,感叹句用叹号,祈使句活用 ...

  8. ruby 中叹号问号的作用

    ruby中的方法可以以问号和叹号结尾,问号通常用于谓语方法,这种方法返回一个布尔值.例如array和hash类都定义了一个empty?方法,这个方法用于测试数据结构中有没有元素.         如果 ...

  9. plsql 中的记录型变量和引用型变量

    /* plsql 中的记录型变量和引用型变量 查询某个员工的姓名和工资 练习记录型变量: 定义变量: emp_rec emp%rowtype; sql语句: select * into emp_rec ...

最新文章

  1. 26.2. Web UI
  2. c# 水晶报表中处理TextObject
  3. 在长文本中当中使用正则表达式匹配限定长度范围的数字串的方法
  4. delphi如何让程序最小化到任务栏(使用Shell_NotifyIcon API函数)
  5. html怎么整体放大,html页面放大时不能铺满整个页面问题
  6. LeetCode 1957. 删除字符使字符串变好
  7. Oracle基本安全之用户、角色和权限操作
  8. Android-动画简介
  9. oracle 在 Linux下安装环境配置
  10. 计算机考试模拟系统无法进入,全国计算机等级考试上机考试模拟系统使用说明...
  11. 南京信息工程大学计算机等级考试代码,南京信息工程大学2016下半年计算机等级考试报名...
  12. 动态多点*** 单云双HUB
  13. 论文笔记_S2D.01-2018-ICRA_Sparse-to-Dense:从稀疏深度样本+单一图像的深度预测
  14. 弹窗php整人,bat整人代码,超级弹窗代码
  15. 如何关闭135,139,445高危端口
  16. 树莓派安装python3.5_一树 - 神奇宝贝百科,关于宝可梦的百科全书
  17. 学习python应用,初识python怎样的感受?
  18. 十二烷基硫酸钠(SDS)将Fe3O4磁性纳米粒子定量地修饰到多壁碳纳米管|化学试剂
  19. 01 QEMU仿真器-模拟器介绍
  20. 2022年十三届蓝桥杯国赛(C/C++大学B组)个人题解

热门文章

  1. UI设计素材|视频类APP图标
  2. java许愿墙_18.JavaScript实现许愿墙效果
  3. 乐高百变工程旋转飞椅知识点_每日一个知识点:关于磁盘的一些事儿
  4. 宁波送餐机器人_重磅合作丨擎朗送餐机器人进驻外婆家,让等餐顾客不再流失...
  5. Maven 动态Web的创建 及 Tomcat的启动
  6. 一次系统调用开销到底有多大?strace、time、perf命令
  7. 程序员写代码的致命缺点
  8. 创建组件“ovalshape”失败_Django的forms组件检验字段\渲染模板
  9. niginx的高可用配置(HA)
  10. MapReduce的API介绍