临界区、管程、信号量介绍

2024-06-04 03:48
文章标签 介绍 信号量 管程 临界

本文主要是介绍临界区、管程、信号量介绍,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

临界区、管程、信号量是操作系统对并发编程支持的三个概念。它们并不是属于java,而是属于操作系统(目前我知道 linux有这三个概念,我觉得windows也应该有只是不确定,否则怎么会支持多核CPU呢?)。

临界区

临界区是线程需要互斥执行的一段代码。临界区的资源是线程共享的,但是执行的返回结果是不确定的。 举个例子:linux系统中的fork()命令会开启一个子线程,每个子线程都应该去调用父线程的方法返回一个PID。假设这个方法是:

NEW_PID = next_pid++

上面的next_pid就是临界资源,是多个线程共享的, 这段代码不是原子操作,但是一定要是互斥的。 临界区只是一个概念,具体实现要看编程语言还操作系统。

信号量

信号量也是一个编程概念,基本由一个整数变量,和两个原子操作组成。这两个原子操作对这个整数变量对行增加和删除。成功才执行后面的代码,失败则阻塞。 具体代码实现可以看我的另一篇博客。
https://blog.csdn.net/u011296165/article/details/80249229

管程

管程对应的英文是Monitor。管程的定义是管理共享变量以及对共享变量的操作过程,让它们支持并发。相对应的java语意是管理java类的成员变量和成员方法,让这个类是线程安全的。
管程是编程语言提供的一种抽象数据结构,它有两个特点

  1. 互斥访问,即任一时刻只有一个线程在执行管程代码;
  2. 正在管程内的线程可以放弃对管程的控制权;
    条件变量(condition variable)是管程内部的实现机制,每个条件变量都代表一种等待的原因,也对应一个等待队列。条件变量有两个操作:wait和signal。这两个条件变量的操作,是某种情况下等待和在某种情况下执行。

MESA模型----java管程使用的模型

管程实现互斥

管程实现互斥就是将共享变量和对共享变量操作的方法封闭起来。如下图,管程X将共享变量queue这个队列和相关操作入队enq()和deq()都封装起来。线程A和线程B如果想要访问共享变量queue()队列,就要使用enq()和deq()方法,enq()和deq()保持了互斥性,这样来保证线程安全。

管程实现同步

MESA的模型图
在这里插入图片描述

图中最大的方框就代表封装的意思, 上方开口就是管程的入口, 入口旁边有一个等待队列。一个管程只能有一个线程去执行,其他线程就进入到这个等待队列。 就像是去医院看医生,一个医生只能同时给一个病人看病,其他拿到号的病人都会在门外等着。

管程里面还有一个条件变量的概念,管程里面还有一个条件变量的概念,管程里面还有一个条件变量的概念这一定非常重要。 后面的东西都是使用了这个条件变量。每一个条件变量都有自己的等待队列,就如图上的条件变量A和条件变量B有两个等待队列。

现在对他的执行过程做一个说明。我们管程中通常两个方法,方法X代表出队操作,方法Y代表入队操作。我们的共享变量V就是队列。我们的假设线程T1在执行方法X出队操作,那么在执行这个出队操作之前是不是应用有一个前置条件,判断这个共享变量V队列不能为空。 而这个前置条件就是条件变量。条件变量的等待队列就是无法获取条件的时候,条件变量执行了wait()方法,将线程放入到了这个条件变量的等待队列中了。
举个生活中的例子:小明去医院看医生,第一步、进医院的就是去取号,然后去对应医生办公室门口等待叫号。这一步对应的就管程入口等待对列第二步 叫到号之后医生让小明去拍X光片,他就去抽血处排队抽血。这一步对应的就是条件变量等待对列第三步 抽完血之后,小明又要去医生办公室门口等待叫号,这一步对应的就是当条件变量符合执行条件就从条件变量队列中释放,但并不是马上去执行,而是去管程入口队列中等待。第四步,小明进入医生办公室看医生,医生让小明在去验上血。小明就要去验血处等待。这一步对应的就是当线程第二次进入管程中,发现条件变量又不符合了,又要去重新进入条件变量队列中重新等待条件符合要求。 当符合要求后在次进入管程入口等待队列,直到进入管程后条件符合要求去执行方法完成。
这里可能有点绕,还请多看几遍。
下面用代码做一下示范。
假定对象A代表“队列不空”这个条件,那么线程进入管程需要判断队列是否为空,如果为空则调用 A.wait()方法。同理当“条件 不空”这个条件满足时,线程T2需要调用 A.notify()来通知A等待队列中的一个线程。 也可以调用 notifyAll()这个方法。

public class BlockedQueue<T>{final Lock lock =new ReentrantLock();// 条件变量:队列不满  final Condition notFull =lock.newCondition();// 条件变量:队列不空  final Condition notEmpty =lock.newCondition();// 入队void enq(T x) {lock.lock();try {while (队列已满){// 等待队列不满 notFull.await();}  // 省略入队操作...// 入队后, 通知可出队notEmpty.signal();}finally {lock.unlock();}}// 出队void deq(){lock.lock();try {while (队列已空){// 等待队列不空notEmpty.await();}// 省略出队操作...// 出队后,通知可入队notFull.signal();}finally {lock.unlock();}  }
}
  1. 对于入队操作,如果队列已满。就需要等待直接队列不满,所以这就用notFull.await()。
  2. 对于出队操作,如果队列为空,就需要等待直接到队不空,所以这就用notEmpty.await()。
  3. 如果入队成功,那么队列就不空,就需要通知队列不空的等待队列。这里就要用notEmpty.signal();
  4. 如果出队成功,那就队列就不满,就需要通知队列不满的等待队列。就这里要用notFull.signal();

总结

java MESA模型
在这里插入图片描述
java MESA 模型中只有一个条件变量,是使用synchronized关键字来实现的。而java sdk并发包中支持多个条件变量,需要开发人员手动去调用加锁和解锁操作。

注:
借鉴极客时间java并发编程和另外一篇博客,那篇博客因电脑突然关机找不到了,如发现请通知,我在加上链接。

这篇关于临界区、管程、信号量介绍的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1028976

相关文章

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

图神经网络模型介绍(1)

我们将图神经网络分为基于谱域的模型和基于空域的模型,并按照发展顺序详解每个类别中的重要模型。 1.1基于谱域的图神经网络         谱域上的图卷积在图学习迈向深度学习的发展历程中起到了关键的作用。本节主要介绍三个具有代表性的谱域图神经网络:谱图卷积网络、切比雪夫网络和图卷积网络。 (1)谱图卷积网络 卷积定理:函数卷积的傅里叶变换是函数傅里叶变换的乘积,即F{f*g}

C++——stack、queue的实现及deque的介绍

目录 1.stack与queue的实现 1.1stack的实现  1.2 queue的实现 2.重温vector、list、stack、queue的介绍 2.1 STL标准库中stack和queue的底层结构  3.deque的简单介绍 3.1为什么选择deque作为stack和queue的底层默认容器  3.2 STL中对stack与queue的模拟实现 ①stack模拟实现

Mysql BLOB类型介绍

BLOB类型的字段用于存储二进制数据 在MySQL中,BLOB类型,包括:TinyBlob、Blob、MediumBlob、LongBlob,这几个类型之间的唯一区别是在存储的大小不同。 TinyBlob 最大 255 Blob 最大 65K MediumBlob 最大 16M LongBlob 最大 4G

FreeRTOS-基本介绍和移植STM32

FreeRTOS-基本介绍和STM32移植 一、裸机开发和操作系统开发介绍二、任务调度和任务状态介绍2.1 任务调度2.1.1 抢占式调度2.1.2 时间片调度 2.2 任务状态 三、FreeRTOS源码和移植STM323.1 FreeRTOS源码3.2 FreeRTOS移植STM323.2.1 代码移植3.2.2 时钟中断配置 一、裸机开发和操作系统开发介绍 裸机:前后台系

nginx介绍及常用功能

什么是nginx nginx跟Apache一样,是一个web服务器(网站服务器),通过HTTP协议提供各种网络服务。 Apache:重量级的,不支持高并发的服务器。在Apache上运行数以万计的并发访问,会导致服务器消耗大量内存。操作系统对其进行进程或线程间的切换也消耗了大量的CPU资源,导致HTTP请求的平均响应速度降低。这些都决定了Apache不可能成为高性能WEB服务器  nginx:

多路转接之select(fd_set介绍,参数详细介绍),实现非阻塞式网络通信

目录 多路转接之select 引入 介绍 fd_set 函数原型 nfds readfds / writefds / exceptfds readfds  总结  fd_set操作接口  timeout timevalue 结构体 传入值 返回值 代码 注意点 -- 调用函数 select的参数填充  获取新连接 注意点 -- 通信时的调用函数 添加新fd到

火语言RPA流程组件介绍--浏览网页

🚩【组件功能】:浏览器打开指定网址或本地html文件 配置预览 配置说明 网址URL 支持T或# 默认FLOW输入项 输入需要打开的网址URL 超时时间 支持T或# 打开网页超时时间 执行后后等待时间(ms) 支持T或# 当前组件执行完成后继续等待的时间 UserAgent 支持T或# User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器