文章内容

  • 1. 信号量
  • 2. 函数
    • 2.1 命名信号量 / 基于文件
    • 2.2 匿名信号量 / 基于内存
  • 3. 读写锁

信号量:用于解决数据竞争,如同火车道上的信号灯,用来管理共享火车道(共享内存)

1. 信号量

分类:

分类 取值 e.g.
二值信号量 0 和 1 指示锁
计数信号量 0 和 n 停车场电子牌

操作:
PV 测试和增加

查看: man sem_overview

接口
头文件: semaphore.h
库: pthread

2. 函数

命名信号量/基于文件

操作 函数
创建 sem_t *sem_open(const char *name, int oflag, mode_t mode,unsigned int value)
删除 int sem_unlink(const char *name)
打开 sem_t *sem_open(const char *name, int oflag)
关闭 int sem_close(sem_t *sem)
挂出 int sem_post(sem_t *sem)
等待 int sem_wait(sem_t *sem)
尝试等待 int sem_trywait(sem_t *sem)
获取信号量的值 int sem_getvalue(sem_t *sem, int *sval)

匿名信号量/基于内存

操作 函数
初始化 int sem_init (sem_t *sem , int pshared, unsigned int value)
销毁 int sem_destroy(sem_t *sem)
挂出 int sem_post(sem_t *sem)
等待 int sem_wait(sem_t *sem)
尝试等待 int sem_trywait(sem_t *sem)
获取信号量的值 int sem_getvalue(sem_t *sem, int *sval)

2.1 命名信号量 / 基于文件

创建信号量 sem_open(文件名, 标志, 权限, 初始值)

加锁,等待 sem_wait(信号量指针)

解锁,挂出 sem_post(信号量指针)

关闭 sem_close(信号量指针)

在共享内存的使用时,通过上锁,实现一个进程完成后另一个进程再执行
父进程先递减,子进程再递减

#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <cstdio>
#include <fcntl.h>
#include <semaphore.h>
#include <sstream>
using namespace std;int main(){sem_t* psem = sem_open("/sem.test",O_CREAT|O_RDWR,0666,1);      // 创建信号量int* p = (int*)mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANON,-1,0);    // 创建并映射共享内存if(MAP_FAILED == p){perror("mmap error");return 1;}*p = 20;if(fork()){for(int i=0;i<10;++i){sem_wait(psem);     // 加锁,等待ostringstream oss;oss << "parent:" << --*p << endl;string s = oss.str();write(STDOUT_FILENO,s.c_str(),s.size()+1);      // 写入sem_post(psem);     // 解锁,挂出}wait(NULL);}else{for(int i=0;i<10;++i){sem_wait(psem);     // 加锁,等待ostringstream oss;oss << "child:" << --*p << endl;string s = oss.str();write(STDOUT_FILENO,s.c_str(),s.size()+1);       // 写入sem_post(psem);     // 解锁,挂出}}munmap(p,sizeof(int));sem_close(psem);psem = NULL;p = NULL;
}

结果为:

[root@foundation1 C++7.13]# g++ fork5.cpp -pthread
[root@foundation1 C++7.13]# ./a.out
parent:19
parent:18
parent:17
parent:16
parent:15
parent:14
parent:13
parent:12
parent:11
parent:10
child:9
child:8
child:7
child:6
child:5
child:4
child:3
child:2
child:1
child:0

编译后面要加 -pthread 库

2.2 匿名信号量 / 基于内存

初始化 sem_init (信号量指针 , 共享方式, 信号量初始值)
共享方式为0:线程间共享
共享方式为1:进程间共享,需要共享内存

销毁 int sem_destroy(sem_t *sem)

完成和上述相同的功能:

#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <cstdio>
#include <fcntl.h>
#include <semaphore.h>
#include <sstream>
using namespace std;int main(){sem_t* psem = (sem_t*)mmap(NULL,sizeof(sem_t),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANON,-1,0);   // 申请共享内存sem_init(psem,1,1);                   // 初始化int* p = (int*)mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANON,-1,0);if(MAP_FAILED == p){perror("mmap error");return 1;}*p = 20;if(fork()){for(int i=0;i<10;++i){sem_wait(psem);     // 加锁ostringstream oss;oss << "parent:" << --*p << endl;string s = oss.str();write(STDOUT_FILENO,s.c_str(),s.size()+1);sem_post(psem);     // 解锁}wait(NULL);}else{for(int i=0;i<10;++i){sem_wait(psem);ostringstream oss;oss << "child:" << --*p << endl;string s = oss.str();write(STDOUT_FILENO,s.c_str(),s.size()+1);sem_post(psem);}}munmap(p,sizeof(int));sem_destroy(psem);psem = NULL;p = NULL;
}

结果为:

parent:19
parent:18
parent:17
parent:16
parent:15
parent:14
parent:13
parent:12
parent:11
parent:10
child:9
child:8
child:7
child:6
child:5
child:4
child:3
child:2
child:1
child:0

3. 读写锁

有时几个读取过程可以共同读,这样可以提高工作效率,读写锁可以分为读锁和写锁
读锁:读的过程中其他读也可以进行读操作
写锁:写的过程中不能进行其他操作

Linux系统编程:IPC信号量相关推荐

  1. Linux系统编程—进程间通信—信号量

    信号量 信号量是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用.在进入一个关键代码段之前,线程必须获取一个信号量:一旦该关键代码段完成了,那么该线程必须释放信号量.其它想 ...

  2. 【Linux | 系统编程】Linux系统编程(文件、进程线程、进程间通信)

    文章目录 Linux系统编程 文件IO open/close函数 read/write函数 文件描述符 阻塞.非阻塞 fcntl函数 lseek函数 传入传出参数 文件系统 文件存储 文件操作 sta ...

  3. Linux系统编程笔记

    文章目录 1.Linux系统编程 2.文件IO 2.1 文件描述符 2.2 open 2.3 perror 2.4 close 2.5 write 2.6 read 2.7 remove 2.8 系统 ...

  4. Linux系统编程【文件IO、进程、进程间通信、信号、线程、互斥】

    linux系统编程 个人通过学习,手打了一份48000字的Linux系统编程的笔记,包含了[文件IO.进程.进程间通信.信号.多线程.互斥]等知识点,并给出了大量的代码案例对每个重要的知识点进行了代码 ...

  5. linux系统编程 小项目,linux系统编程小项目.doc

    linux系统编程小项目.doc 一.项目概述简单智能远程监控功能服务器端1.服务器端利用随机数模拟向串口读取传感数据,需要模拟的传感数据要求有温度.湿度.光照.室内噪音度等等.2.服务器要求在数据保 ...

  6. linux系统发送信号的系统调用是,linux系统编程之信号:信号发送函数sigqueue和信号安装函数sigaction...

    信号发送函数sigqueue和信号安装函数sigaction sigaction函数用于改变进程接收到特定信号后的行为. sigqueue()是比较新的发送信号系统调用,主要是针对实时信号提出的(当然 ...

  7. linux线程并不真正并行,Linux系统编程学习札记(十二)线程1

    Linux系统编程学习笔记(十二)线程1 线程1: 线程和进程类似,但是线程之间能够共享更多的信息.一个进程中的所有线程可以共享进程文件描述符和内存. 有了多线程控制,我们可以把我们的程序设计成为在一 ...

  8. 【Linux】一步一步学Linux系统编程教程汇总(暂时暂停更新......)

    00. 目录 文章目录 00. 目录 01. 概述和标准 02. 文件操作 03. 进程概念 04. 进程间通信 05. 多线程 06. 信号 07. 同步与互斥 08. 高级IO 09. 其它 10 ...

  9. 【Linux系统编程】进程间通信之无名管道

    00. 目录 文章目录 00. 目录 01. 管道概述 02. 管道创建函数 03. 管道的特性 04. 管道设置非阻塞 05. 附录 01. 管道概述 管道也叫无名管道,它是是 UNIX 系统 IP ...

  10. 【Linux系统编程】进程间通信概述

    00. 目录 文章目录 00. 目录 01. 进程间通信概述 02. 进程间通信目的 03. 进程间通信机制 04. 附录 01. 进程间通信概述 进程是一个独立的资源分配单元,不同进程(这里所说的进 ...

最新文章

  1. 用高中数学理解AI “深度学习”的基本原理
  2. spring 框架概述
  3. 广告贴——希望大家有空能够参加11月27日的《葵花宝典——WPF自学手册》签名售书活动...
  4. 关于Jeecg互联网化dubbo改造方案(下)
  5. 积分路径上有奇点的积分_【Euler积分】Ch 2. Gamma函数的定义
  6. emerald sword(打倒大魔王)
  7. 用HE提供的免费DNS解析服务通过IPv6 DNS检测
  8. MATLAB(R2021a)软件下载和安装教程
  9. labview高级视频150讲下载_视频剪辑篇|讲真的,这些软件素材资源我真舍不得分享!(附下载包)...
  10. You Only Look Once: Unified, Real-Time Object Detection(YOLO论文中英同步翻译)
  11. 历经30年,仍未解决通讯难题,水下机器人是虚假繁荣吗?
  12. 华为鸿蒙到底卡不卡,华为mate book14,办公作图就靠它了
  13. 原型模型| 软件工程
  14. Python斗鱼直播间自动发弹幕脚本
  15. idea怎么设置成中文
  16. python turtle画房子代码里面的窗子,如何用python画房子_用python画一个小房子
  17. 关于NullPointerException空指针异常的解决办法
  18. Tomcat7之性能优化
  19. 常见Web源码泄漏及其利用
  20. 使用setuptools构建python包

热门文章

  1. Sketch 资源合集
  2. 诺基亚奢华手机:高配置+8.78万元
  3. Unity3D休闲射击类游戏《Survival Shooter》完整源码
  4. Scala特质trait
  5. 百度地图转换腾讯地图 php,用PHP实现腾讯地图和百度地图的相互转换范例
  6. 安卓应用 - 公开市场上传投放
  7. sw制作arduino模型
  8. Adroid11,拍照,裁剪以及保存图片
  9. Hbase——常见错误
  10. rip路由协议java_路由协议之RIP