[linux下]理解Semaphore及其用法详解

2023-05-16

2009-05-12 13:13
Mutex是一把钥匙,一个人拿了就可进入一个房间,出来的时候把钥匙交给队列的第一个。一般的用法是用于串行化对critical section代码的访问,保证这段代码不会被并行的运行。



Semaphore是一件可以容纳N人的房间,如果人不满就可以进去,如果人满了,就要等待有人出来。对于N=1的情况,称为binary semaphore。一般的用法是,用于限制对于某一资源的同时访问。



Binary semaphoreMutex的差异:

在 有的系统中Binary semaphore与Mutex是没有差异的。在有的系统上,主要的差异是mutex一定要由获得锁的进程来释放。而semaphore可以由其它进程释 放(这时的semaphore实际就是个原子的变量,大家可以加或减),因此semaphore可以用于进程间同步。Semaphore的同步功能是所有 系统都支持的,而Mutex能否由其他进程释放则未定,因此建议mutex只用于保护critical section。而semaphore则用于保护某变量,或者同步。



关于semaphore和mutex的区别,网上有著名的厕所理论(http://koti.mbnet.fi/niclasw/MutexSemaphore.html):

Mutex:Is a key to a toilet. One person can have the key - occupy the toilet - at the time. When finished, the person gives (frees) the key to the next person in the queue.Officially: “Mutexes are typically used to serialise access to a section of re-entrant code that cannot be executed concurrently by more than one thread. A mutex object only allows one thread into a controlled section, forcing other threads which attempt to gain access to that section to wait until the first thread has exited from that section.”
Ref: Symbian Developer Library(A mutex is really a semaphore with value 1.)

Semaphore:

Is the number of free identical toilet keys. Example, say we have four toilets with identical locks and keys. The semaphore count - the count of keys - is set to 4 at beginning (all four toilets are free), then the count value is decremented as people are coming in. If all toilets are full, ie. there are no free keys left, the semaphore count is 0. Now, when eq. one person leaves the toilet, semaphore is increased to 1 (one free key), and given to the next person in the queue.

Officially: “A semaphore restricts the number of simultaneous users of a shared resource up to a maximum number. Threads can request access to the resource (decrementing the semaphore), and can signal that they have finished using the resource (incrementing the semaphore).”
Ref: Symbian Developer Library

所以,mutex就是一个binary semaphore (值就是0或者1)。但是他们的区别又在哪里呢?主要有两个方面:

    * 初始状态不一样:mutex的初始值是1(表示锁available),而semaphore的初始值是0(表示unsignaled的状态)。随后的操 作基本一样。mutex_lock和sem_post都把值从0变成1,mutex_unlock和sem_wait都把值从1变成0(如果值是零就等 待)。初始值决定了:虽然mutex_lock和sem_wait都是执行V操作,但是sem_wait将立刻将当前线程block住,直到有其他线程 post;mutex_lock在初始状态下是可以进入的。
    * 用法不一样(对称 vs. 非对称):这里说的是“用法”。Semaphore实现了signal,但是mutex也有signal(当一个线程lock后另外一个线程 unlock,lock住的线程将收到这个signal继续运行)。在mutex的使用中,模型是对称的。unlock的线程也要先lock。而 semaphore则是非对称的模型,对于一个semaphore,只有一方post,另外一方只wait。就拿上面的厕所理论来说,mutex是一个钥 匙不断重复的使用,传递在各个线程之间,而semaphore择是一方不断的制造钥匙,而供另外一方使用(另外一方不用归还)。

前面的实验证明,mutex确实能够做到post和wait的功能,只是大家不用而已,因为它是“mutex”不是semaphore。


下面给出一个例子:

要 让一个thread在背景不断的执行,最简单的方式就是在该thread执行无穷回圈,如while(1) {},这种写法虽可行,却会让CPU飙高到100%,因为CPU一直死死的等,其实比较好的方法是,背景平时在Sleep状态,当前景呼叫背景时,背景马 上被唤醒,执行该做的事,做完马上Sleep,等待前景呼叫。当背景sem_wait()时,就是马上处于Sleep状态,当前景sem_post() 时,会马上换起背景执行,如此就可避免CPU 100%的情形了。


/**//*
    (C) OOMusou 2006 http://oomusou.cnblogs.com

     Filename : pthread_create_semaphore.cpp
     Compiler : gcc 4.10 on Fedora 5 / gcc 3.4 on Cygwin 1.5.21
     Description : Demo how to create thread with semaphore in Linux.
     Release : 12/03/2006
     Compile : g++ -lpthread pthread_create_semaphore.cpp
    */
#include <stdio.h> // printf(),
#include <stdlib.h> // exit(), EXIT_SUCCESS
#include <pthread.h> // pthread_create(), pthread_join()
#include <semaphore.h> // sem_init()

sem_t binSem;

void* helloWorld(void* arg);

int main() {
     // Result for System call
    int res = 0;

     // Initialize semaphore
     res = sem_init(&binSem, 0, 0);
    if (res) {
         printf("Semaphore initialization failed!!\n");
         exit(EXIT_FAILURE);
     }

     // Create thread
     pthread_t thdHelloWorld;
     res = pthread_create(&thdHelloWorld, NULL, helloWorld, NULL);
    if (res) {
         printf("Thread creation failed!!\n");
         exit(EXIT_FAILURE);
     }

    while(1) {
         // Post semaphore
         sem_post(&binSem);
         printf("In main, sleep several seconds.\n");
        sleep(1);
     }

     // Wait for thread synchronization
     void *threadResult;
     res = pthread_join(thdHelloWorld, &threadResult);
    if (res) {
         printf("Thread join failed!!\n");
         exit(EXIT_FAILURE);
     }

     exit(EXIT_SUCCESS);
}

void* helloWorld(void* arg) {
    while(1) {
         // Wait semaphore
         sem_wait(&binSem);
         printf("Hello World\n");
     }
}


编译运行:


[root@localhost semaphore]# gcc semaphore.-lpthread
[root@localhost semaphore]# ./a.out
In main, sleep several seconds.
Hello World
In main, sleep several seconds.
Hello World
In main, sleep several seconds.
Hello World
In main, sleep several seconds.
Hello World

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[linux下]理解Semaphore及其用法详解 的相关文章

  • opencv检测矩形

    参考 xff1a 使用OpenCV检测图像中的矩形 知来者逆的博客 CSDN博客 opencv检测图像中的矩形 1 得到原始图像之后 xff0c 代码处理的步骤是 xff1a xff08 1 xff09 滤波增强边缘 xff08 2 xff
  • 模型大小 与参数量计算

    1 model size 就是模型的大小 xff0c 我们一般使用参数量parameter来衡量 xff0c 注意 xff0c 它的单位是个 但是由于很多模型参数量太大 xff0c 所以一般取一个更方便的单位 xff1a 兆 M 来衡量 比
  • 多传感器融合track fusion

    这个讲的不错 xff1a 第六篇 无人驾驶的sensor fusion和多目标tracking 知乎 题图来自matlab公开课 sensor fusion and tracking 侵权删 但凡目前自动驾驶公司的一线工程师 xff0c 或
  • windows software develop kit 安装卸载笔记

    windows software develop kit 是visual studio 的开发工具库 安装 xff1a 打开Visual Studio Installer中 xff0c 1 Visual Studio Installer所在
  • px4flow智能光学流动传感器

    PX4Flow 是一款智能光学流动传感器 传感器拥有原生 752 480 像素分辨率 xff0c 计算光学流的过程中采用了4倍分级和剪裁算法 xff0c 计算速度达到250Hz xff08 白天 xff0c 室外 xff09 xff0c 具
  • Spring源码之ConfigurableEnvironment Environment ConfigurablePropertyResolver PropertyResolver

    PropertyResolver xff1a 接口以解析任何底层资源的属性 boolean containsProperty String key 返回给定的属性KEY是否可用于解析 xff0c 如果给定密钥的值不是NULL String
  • pyqt setStyleSheet用法

    设置背景 xff1a self content splitter setStyleSheet 34 QSplitter handle background lightgray 34 设置padding self detailFrame pi
  • [音乐] 随遇而安

    黄霑真的很适合唱这种充满了江湖气息的歌 xff0c 这首歌的经典程度不亚于 沧海一声笑 有兴趣的自己搜来听听吧 人外有人山外有山 不怕拼命怕平凡 有得有失有欠有还 老天不许人太贪 挺起胸膛咬紧牙关 生死容易低头难 就算当不成英雄 也要是一条
  • 视觉SLAM十四讲(一)基础知识

    SLAM是Simultaneous Localization and Mapping的缩写 xff0c 中文 同时定位于地图构建 双目SLAM的距离估计是比较左右眼的图像获得的 xff0c 非常消耗计算资源 xff0c 需要使用GPU和FP
  • E-R概念模型

    E R 概念模型 1 信息的现实世界 我们要管理的客观存在的各种事物 事务之间的相互联系及事物的发生 变化过程 1 实体 Entity 现实世界中存在的可以相互区分的事物或概念称为实体 2 实体的特征 Entity Characterist
  • 数据库设计说明书参考模板

    数据库设计说明书参考模板1 xff0e 引言 1 1 项目名称 1 2项目背景和内容概要 xff08 项目的委托单位 开发单位 主管部门 与其它项目的关系 xff0c 与其他机构的关系等 xff09 1 3相关资料 缩略语 定义 xff08
  • 事件的简单解释:

    事件的简单解释 事件是对象发送的消息 xff0c 以发信号通知操作的发生 操作可能是由用户交互 xff08 例如鼠标单击 xff09 引起的 xff0c 也可能是由某些其他的程序逻辑触发的 引发 xff08 触发 xff09 事件的对象叫做
  • .Net中把图片等文件放入DLL中,并在程序中引用

    摘要 有时我们需要隐藏程序中的一些资源 xff0c 比如游戏 xff0c 过关后才能看到图片 xff0c 那么图片就必须隐藏起来 xff0c 否则不用玩这个游戏就可以看到你的图片了 xff0c 呵呵 本文就讲述了如何把文件 xff08 比如
  • VB中如何保存图片到 Sql Server中,又如何读取出来??

    Const BLOCKSIZE 61 8192 Public Sub SaveToDB ByRef Fld As ADODB Field DiskFile As String Dim byteData As Byte 39 定义数据块数组
  • 在Vf中如何将Excel数据导入(用Vf来导)?

    请大侠们赐教 使用import命令 xff0c 如 xff1a IMPORT FROM 表1 xls TYPE xls 将表1 xls导入为表1 dbf 点击 文件 xff0d gt 导入 xff0d gt 类型选择 xff1a Micro
  • 3.3 生产管理系统需求分析

    根据以上对生产管理内容和生产管理系统的分析 xff0c 一个标准的MRP生产管理系统应该包括如图3 12所示的几大功能 除此之外系统还应包括信息系统必须具备的通用功能 xff0c 例如系统管理 权限设置 数据备份与恢复等 xff0c 这些功
  • Spring源码之事物注解@Transactional原理(源码层面)

    官方文档地址 xff1a https docs spring io spring docs 4 3 21 RELEASE spring framework reference htmlsingle transaction 我翻译的地址 xf
  • 設計公司軟件開發需求分析流程

    工作流程 一 平面设计客户合作流程 信息收集 1 客户提出工作要求 2 客户提供相美文本及图片资料 公司介绍 项目描述 基本设计要求 提案 1 双方就设计内容进行协商 xff0c 修改 补充 xff0c 以达成共识 2双方确定设计具体细节及
  • DBcontext应用于已存在数据库

    EF4 1有三种方式来进行数据操作及持久化 分别是Database First Model First Code first xff0c 前面都已经简单介绍过了 下面简单小结一下 xff1a 1 Database First 是基于已存在的
  • 没有为该对象定义无参数的构造函数(MVC 之DefaultControllerFactory 依赖注入)

    Asp net mvc2中提供很多可以扩展的地方 xff0c 利用这些扩展之后 xff0c asp net mvc使用起来更加灵活 Simone Chiaretta曾写过一篇文章 xff1a 13 ASP NET MVC extensibi

随机推荐

  • Entity Framework 学习总结之一:ADO.NET 实体框架概述

    ADO NET 实体框架概述 新版本中的 ADO NET 以新实体框架为特色 它使开发人员可以通过对象模型 xff08 而不是逻辑 关系数据模型 xff09 专注于数据 实体框架有助于将逻辑数据架构抽象为概念模型 xff0c 并且允许以多种
  • Entity Framework 学习总结之四:对象服务介绍使用

    System Data Objects System Data Entity dll 该命名空间包含一些类 xff0c 用于提供对 对象服务 的核心功能的访问 这些类使您可以藉由作为实体类型实例的强类型 CLR 对象来查询 插入 更新和删除
  • Entity Framework 学习总结之四:对象服务介绍使用

    System Data Objects System Data Entity dll 该命名空间包含一些类 xff0c 用于提供对对象服务的核心功能的访问 这些类使您可以藉由作为实体类型实例的强类型 CLR 对象来查询 插入 更新和删除数据
  • 未执行的URL(MVC异常)

    昨天开始就碰到在IIS里面通过URL无法直接访问到图片 xff0c 提示错误 xff0c 所以经过研究发现 xff0c 合理的配置节应该如下 先改成集成模式 xff0c 然后再改成经典模式 lt system webServer gt lt
  • PIX学习路径-1-选择PIXHAWK作为飞控学习的起点

    xff08 先声明出处 xff1a http blog csdn net qq 21842557 article details 52214425 xff09 创业领域现在最火爆的是什么 xff1f 无疑是机器人和无人机 越来越多的巨头和V
  • PIX学习路径-3-PIXHAWK二次开发之前需要知道的事

    现在作为一个consumer xff0c 能够实现将飞机装配 xff0c 使用MP进行固件烧录 xff0c 初始化校准 xff0c 然后还能够调节PID xff0c 这样算是一个合格的consumer了 xff0c 现在希望对PIXHAWK
  • Java面试题全集(上)

    2013年年底的时候 xff0c 我看到了网上流传的一个叫做 Java面试题大全 的东西 xff0c 认真的阅读了以后发现里面的很多题目是重复且没有价值的题目 xff0c 还有不少的参考答案也是错误的 xff0c 于是我花了半个月时间对这个
  • Netty学习:Channel及其内部接口Unsafe

    连接到网络套接字或组件的一种连接 xff0c 它能够进行I O操作 xff0c 如读 写 连接和绑定 通道为用户提供 通道的当前状态 例如是否打开 它是连接吗 通道的 64 linkplain ChannelConfig配置参数 如接收缓冲
  • 拥抱开源

    使用linux ubuntu 已经一个月多了 xff0c 偶尔用windows是因为要改vb delphi net的程序 在linux下 xff0c 似乎多数软件都是开源的 xff0c 免费的 如今我算是终于义无反顾的走上了这条路了 jav
  • STM32 | C语言对寄存器的封装

    说明 xff1a 这里以GPIO外设为例 xff0c 介绍C语言对寄存器的封装 以此类推其他外设同样可以用这种方法来封装 本文有两部分构成 xff1a 1 介绍宏定义 2 使用结构体封装寄存器列表 1 宏定义 以封装STM32 GPIOH为
  • Intel CPU(i3、i5、i7、i9)型号、性能详细解读

    一 Intel CPU的性能比较 xff1a 它们分为高中低端 xff0c 最低端的G系列 xff0c 然后是低端i3系列 xff0c 中端i5系列 xff0c 高端i7系列和至尊i9系列 Intel CPU 末尾字母含义 xff08 M
  • 字符串搜索函数

    一 字符串中找字符 char strchr const char s int c 表示从左边 开始找这个字符第一次出现的位置 char strrchar const char s int c 表示 从右边 开始找这个字符第一次出现的位置 注
  • 4. Service

    4 Service k8s 中的Pod是朝生夕死的 xff0c 并且是不会重生的 xff0c 尤其是在ReplicaSets中动态创建或销毁Pod 然而每个Pod可以获取自己的IP地址 xff0c 即使这些IP地址是不稳定的 xff08 重
  • STM32 Free RTOS实战

    FreeRTOS是一个开源的实时操作系统 使用的平台 xff1a 秉火STM32 Cortex M3内核开发板 xff0c Free RTOS v8 2 3 多任务流水灯 span class token builtin class nam
  • 参考 | 升级 Win11 移动热点开不了或者开了连不上

    讲道理 就很离谱 一开始我升级了 Win11 后 突然发现 移动热点 开不了了 就是那种 开了之后 手机 ipad 能检测到电脑移动热点的信号 但是会出现这两种情况 死活连不上连上了 在移动端显示 无互联网连接 解决办法 打开 移动热点 打
  • 在 Linux 上安装和使用恶意软件检测工具 LMD

    在 Linux 上安装和使用恶意软件检测工具 LMD xff0c 是个相当简单的过程 xff0c 1 下载资源 wget http www rfxn com downloads maldetect current tar gz 2 解压缩资
  • Docker 使用Dockerfile创建镜像

    基本结构 Dockerfle 由 一行行命令语句组成 xff0c 并且支持以 xff03 开头的注释行 一般而言 xff0c Dockerfle 主体内容分为四部分 xff1a 基础镜像信息 维护者信息 镜像操作指令和容器启动时执行指令 e
  • 为啥我的APP功能引导设计这么low?如何做好功能引导设计?

    功能引导设计历史版本 Level1 APP第一次打开的浏览页 展示主要功能及简单使用方式 xff1b Level2 引导流程页 使用 xff1f 方式在界面右上角 xff0c 点击后展示使用流程详情 xff1b Level3 蒙层 可以有上
  • 【Xshell无法连接虚拟机问题】xshell无法连接虚拟机Ubuntu系统问题

    问题描述 xff1a 电脑新安装虚拟机 xff0c 并且安装Ubuntu系统 xff0c 通过Xshell工具无法连问题 原因是新linux系统未安装 ssh 服务导致 xff0c Xshell连接是依赖 ssh 服务实现的 下面让我们解决
  • [linux下]理解Semaphore及其用法详解

    2009 05 12 13 13 Mutex 是一把钥匙 xff0c 一个人拿了就可进入一个房间 xff0c 出来的时候把钥匙交给队列的第一个 一般的用法是用于串行化对critical section代码的访问 xff0c 保证这段代码不会