Linux系统编程:IPC信号量
文章内容
- 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信号量相关推荐
- Linux系统编程—进程间通信—信号量
信号量 信号量是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用.在进入一个关键代码段之前,线程必须获取一个信号量:一旦该关键代码段完成了,那么该线程必须释放信号量.其它想 ...
- 【Linux | 系统编程】Linux系统编程(文件、进程线程、进程间通信)
文章目录 Linux系统编程 文件IO open/close函数 read/write函数 文件描述符 阻塞.非阻塞 fcntl函数 lseek函数 传入传出参数 文件系统 文件存储 文件操作 sta ...
- 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 系统 ...
- Linux系统编程【文件IO、进程、进程间通信、信号、线程、互斥】
linux系统编程 个人通过学习,手打了一份48000字的Linux系统编程的笔记,包含了[文件IO.进程.进程间通信.信号.多线程.互斥]等知识点,并给出了大量的代码案例对每个重要的知识点进行了代码 ...
- linux系统编程 小项目,linux系统编程小项目.doc
linux系统编程小项目.doc 一.项目概述简单智能远程监控功能服务器端1.服务器端利用随机数模拟向串口读取传感数据,需要模拟的传感数据要求有温度.湿度.光照.室内噪音度等等.2.服务器要求在数据保 ...
- linux系统发送信号的系统调用是,linux系统编程之信号:信号发送函数sigqueue和信号安装函数sigaction...
信号发送函数sigqueue和信号安装函数sigaction sigaction函数用于改变进程接收到特定信号后的行为. sigqueue()是比较新的发送信号系统调用,主要是针对实时信号提出的(当然 ...
- linux线程并不真正并行,Linux系统编程学习札记(十二)线程1
Linux系统编程学习笔记(十二)线程1 线程1: 线程和进程类似,但是线程之间能够共享更多的信息.一个进程中的所有线程可以共享进程文件描述符和内存. 有了多线程控制,我们可以把我们的程序设计成为在一 ...
- 【Linux】一步一步学Linux系统编程教程汇总(暂时暂停更新......)
00. 目录 文章目录 00. 目录 01. 概述和标准 02. 文件操作 03. 进程概念 04. 进程间通信 05. 多线程 06. 信号 07. 同步与互斥 08. 高级IO 09. 其它 10 ...
- 【Linux系统编程】进程间通信之无名管道
00. 目录 文章目录 00. 目录 01. 管道概述 02. 管道创建函数 03. 管道的特性 04. 管道设置非阻塞 05. 附录 01. 管道概述 管道也叫无名管道,它是是 UNIX 系统 IP ...
- 【Linux系统编程】进程间通信概述
00. 目录 文章目录 00. 目录 01. 进程间通信概述 02. 进程间通信目的 03. 进程间通信机制 04. 附录 01. 进程间通信概述 进程是一个独立的资源分配单元,不同进程(这里所说的进 ...
最新文章
- 用高中数学理解AI “深度学习”的基本原理
- spring 框架概述
- 广告贴——希望大家有空能够参加11月27日的《葵花宝典——WPF自学手册》签名售书活动...
- 关于Jeecg互联网化dubbo改造方案(下)
- 积分路径上有奇点的积分_【Euler积分】Ch 2. Gamma函数的定义
- emerald sword(打倒大魔王)
- 用HE提供的免费DNS解析服务通过IPv6 DNS检测
- MATLAB(R2021a)软件下载和安装教程
- labview高级视频150讲下载_视频剪辑篇|讲真的,这些软件素材资源我真舍不得分享!(附下载包)...
- You Only Look Once: Unified, Real-Time Object Detection(YOLO论文中英同步翻译)
- 历经30年,仍未解决通讯难题,水下机器人是虚假繁荣吗?
- 华为鸿蒙到底卡不卡,华为mate book14,办公作图就靠它了
- 原型模型| 软件工程
- Python斗鱼直播间自动发弹幕脚本
- idea怎么设置成中文
- python turtle画房子代码里面的窗子,如何用python画房子_用python画一个小房子
- 关于NullPointerException空指针异常的解决办法
- Tomcat7之性能优化
- 常见Web源码泄漏及其利用
- 使用setuptools构建python包