linux提供了互斥量pthread_mutex_t(pthread库) 用于线程间同步,进程间同步提供了信号量sem_t。如果把pthread_mutex_t放到共享内存中,并将其属性设置为PTHREAD_PROCESS_SHARED,则也能实现进程间的同步,相对而言比较麻烦。一般直接使用信号量更加方便。

这里讨论使用具名信号量以便在无血缘关系的进程之间做同步,主要涉及下面5个函数:

sem_open();//打开或者创建信号量
sem_wait();//获取信号量
sem_post();//挂出信号量
sem_close();//关闭信号量
sem_unlink();//销毁信号量

其中sem_unlink()的行为比较让人迷惑,linux内核文档描述为:

DESCRIPTIONsem_unlink() removes the named semaphore referred to by name.  The semaphore name is removed immediately.  Thesemaphore is destroyed once all other processes that have the semaphore open close it.

意思是执行该函数,会立即移除信号量的id名,并尝试销毁对应的信号量实体,只有所有打开了该信号量的进程都执行了sem_close(),执行sem_unlink()时才会真正销毁这个信号量。问题就出现了,id名与信号量实体可能出现分离,因为当某个进程A关闭了信号量(也就是执行了sem_close)并尝试执行sem_unlink的时候,并不能确保其他进程关闭了信号量,结果是信号量实体无法被真正销毁,它依然在内核中存在,且其他使用该信号量实体的进程依然可以工作正常。问题是,当进程A再次打开这个信号量时(使用sem_open(),id名不变),已经无法通过id名找到之前那个信号量实体了,打开的是一个全新的信号量,虽然id名与之前一样,内容却已经没有关联了。

这样一来,进程A就无法与其他进程同步了。只有其他进程也执行一次sem_close,并重新打开这个id名(sem_open()),才能重新连接到进程A打开的那个信号量实体,继续同步。因此“The semaphore name is removed immediately”,应该理解为"立即解除name 与信号量实体的绑定关系",且解除之后无法重新绑定。

在使用共享内存的过程中,shmctl(id,IPC_RMID,NULL)移除共享内存,好像也有类似的问题,没有实测过。

总结:

通常当一个进程退出时,需要关闭已经打开的信号量(sem_close),如果信号量属于这个进程(在这个进程里面create),还应该执行sem_unlink;如果信号量的归属权不是该进程,则只应该执行关闭。

现实使用的时候,进程可能异常挂掉退出,没有执行到sem_close这一步,甚至还没有来得及挂出信号量(sem_post)程序就挂了,问题比较复杂,不仅可能存在数据安全,还很有可能造成死锁。所以最好是当某个进程重启了,其他相关进程也重启一下,确保所有进程打开的是同一个信号量实体,可以一定程度避免信号量和共享内存连接异常的问题。

当然,最好是不要让程序有异常挂掉的情况,应该做好异常捕获和处理,减少程序未定义行为。

记录一次linux信号量sem_t使用bug相关推荐

  1. Linux信号量 sem_t简介

    简介请移步: https://blog.csdn.net/qq_19923217/article/details/82902442 https://blog.csdn.net/evsqiezi/art ...

  2. 最全面的 linux 信号量解析

    一.什么是信号量 信号量的使用主要是用来保护共享资源,使得资源在一个时刻只有一个进程(线程)所拥有. 信号量的值为正的时候,说明它空闲.所测试的线程可以锁定而使用它.若为 0,说明它被占用,测试的线程 ...

  3. 记录第一次使用linux部署springbootweb项目

    记录第一次使用linux部署springbootweb项目 收获感受 经过一下午的安装虚拟机.Linux系统.JDK1.8,项目打包,解决bug,终于项目部署成功!哈哈哈哈哈哈哈哈哈 收获还是不错的, ...

  4. Linux·信号量全解

    目录 信号量 进程间 [无名信号量完成 有血缘关系的进程间 互斥] 知识点2[有名信号量 没有血缘进程互斥] 1.创建一个有名信号量 2.信号量的关闭: 3.信号量文件的删除 4.P操作 sem_wa ...

  5. linux申请信号量,linux 信号量

    https://www.jianshu.com/p/6e72ff770244 无名信号量 只适合用于一个进程的不同线程 #include #include #include #include #inc ...

  6. linux terminal教程,Linux入门教程 - 如何记录和重放Linux终端会话

    原标题:Linux入门教程 - 如何记录和重放Linux终端会话 来自:https://www.linuxmi.com/replay-linux.html 使用命令,我们可以在type文件中记录终端会 ...

  7. Linux系统下搭建BUG管理系统---禅道

    Linux系统下搭建BUG管理系统---禅道 事前准备: Linux系统服务器,centos6.5版本 Windows系统本地电脑 禅道压缩包 Xshell4.xftp管理工具 1.安装mysql y ...

  8. 编译linux源码报错,记录一次Linux内核源码编译实验

    记录一次Linux内核源码编译实验 文章目录 记录一次Linux内核源码编译实验 0. 实验环境 1. 选择.下载内核源码 2. 安装必要的依赖软件以及性能要求 3. 解压.配置和编译内核源码 3.1 ...

  9. 简洁介绍信号量sem_t的起因、原理与使用

    简洁介绍信号量sem_t的起因.原理与使用 起因: 在对应用程序优化加速时,会使用多线程技术来进行加速.使用软件多线程可以让用户与底层硬件进行隔离.即不管实际底层硬件是否有多个执行单元,都可以使用多线 ...

  10. 如何向Linux内核提交代码,华人教授向 Linux 内核提交含 Bug 代码,Linux 管理员直接拉黑整所大学!...

    技术编辑:小魔丨发自 思否编辑部公众号:SegmentFault Linux 内核是目前最大的软件项目之一,拥有 2800 万行代码.世界各地的贡献者每天向 Linux 内核管理员提交大量 patch ...

最新文章

  1. 6位有符号补码阵列乘法器_C/C++学习日记:原码、反码和补码
  2. 微软职位内部推荐-Software Engineer II-Data Mini
  3. 域名无法加入域解决方法
  4. 把数据保存到cook_JavaScript数据存储 Cookie篇
  5. ApkTool反编译出错brut.common.brutexception及java.io.filenotfoundexception 之一
  6. SpringMVC流程图示
  7. Java中的查找树和哈希表(一级)
  8. Pythont特殊语法filter,map,reduce,apply
  9. Linux环境_源码安装LibreOffice实现文件在线预览doc,doxc,xls,xlsx,ppt,pptx 文件
  10. 自动化数据增强:实践、理论和新方向
  11. linux能秒创虚拟机吗,linux下5秒创建rhel7虚拟机
  12. SP913 QTREE2 - Query on a tree II
  13. Window环境下使用C#调用VBScript、JavaScript等脚本
  14. 重复抽样与非重复抽样
  15. IOS 保存图片至相册
  16. 没有 4K 和新处理器,任天堂的新 Switch 为什么还能吸引圈外玩家买单?
  17. PlayReady 和WideVine
  18. 【STM32F407开发板用户手册】第2章 STM32F407的开发环境搭建
  19. c语言程序设计网课作业答案,知到C语言程序设计基础网课答案
  20. Modern C++ JSON nlohmann::json 使用详解

热门文章

  1. 对sql文件进行读取并通过JDBC批量执行
  2. Notes Ninth Day-渗透攻击-红队-打入内网
  3. Ubuntu下安装微信
  4. linux中找不到vim命令
  5. 大四学生发明文言文编程语言,设计思路清奇
  6. abaqus单位问题
  7. App测试如何进行?手机app测试要点
  8. 微信公众平台开发资源集锦
  9. QImage与QPixmap区别
  10. 3DMM(人脸3D形变统计模型)