进程同步与相互排斥:POSIX有名信号量
在 POSIX 标准中,信号量分两种,一种是无名信号量,一种是有名信号量。
无名信号量一般用于线程间同步或相互排斥,而有名信号量一般用于进程间同步或相互排斥。
它们的差别和管道及命名管道的差别类似。无名信号量则直接保存在内存中,而有名信号量要求创建一个文件。前面我们学习了无名信号量的使用(详情请看《无名信号量》)。这里我们学习有名信号量的使用。
1)创建一个有名信号量
所需头文件:
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
当有名信号量存在时使用:
sem_t *sem_open(const char *name, int oflag);
当有名信号量不存在时使用:
sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
功能:
创建一个有名信号量。
參数:
name:信号量文件名称。注意,不能指定路径名。由于有名信号量,默认放在/dev/shm 里。例如以下图:
flags:sem_open() 函数的行为标志。
mode:文件权限(可读、可写、可运行)的设置。
value:信号量初始值。
返回值:
成功:信号量的地址
失败:SEM_FAILED
2)关闭有名信号量
所需头文件:
#include <semaphore.h>
int sem_close(sem_t *sem);
功能:
关闭有名信号量。
參数:
sem:指向信号量的指针。
返回值:
成功:0
失败:-1
3)删除有名信号量文件
所需头文件:
#include <semaphore.h>
int sem_unlink(const char *name);
功能:
删除有名信号量的文件。
參数:
name:有名信号量文件名称。
返回值:
成功:0
失败:-1
4)信号量 PV 操作
有名信号量实现进程间相互排斥功能:
- #include<stdio.h>
- #include<semaphore.h>
- #include<fcntl.h>
- #include<unistd.h>
- #include<sys/stat.h>
- #include<sys/types.h>
- void printer(sem_t *sem, char *str)
- {
- sem_wait(sem); //信号量减一
- while(*str!='\0')
- {
- putchar(*str);
- fflush(stdout);
- str++;
- sleep(1);
- }
- printf("\n");
- sem_post(sem); //信号量加一
- }
- int main(int argc, char *argv[])
- {
- pid_t pid;
- sem_t *sem = NULL;
- pid = fork(); //创建进程
- if(pid<0){ //出错
- perror("fork error");
- }else if(pid == 0){ //子进程
- //跟open()打开方式非常相似,不同进程仅仅要名字一样。那么打开的就是同一个有名信号量
- sem = sem_open("name_sem", O_CREAT|O_RDWR, 0666, 1); //信号量值为 1
- if(sem == SEM_FAILED){ //有名信号量创建失败
- perror("sem_open");
- return -1;
- }
- char *str1 = "hello";
- printer(sem, str1); //打印
- sem_close(sem); //关闭有名信号量
- _exit(1);
- }else if(pid > 0){ //父进程
- //跟open()打开方式非常相似,不同进程仅仅要名字一样,那么打开的就是同一个有名信号量
- sem = sem_open("name_sem", O_CREAT|O_RDWR, 0666, 1); //信号量值为 1
- if(sem == SEM_FAILED){//有名信号量创建失败
- perror("sem_open");
- return -1;
- }
- char *str2 = "world";
- printer(sem, str2); //打印
- sem_close(sem); //关闭有名信号量
- wait(pid, NULL); //等待子进程结束
- }
- sem_unlink("name_sem");//删除有名信号量
- return 0;
- }
执行结果例如以下:
有名信号量实现进程间同步功能(print2 先打印。再到 print1 打印):
print1.c 代码例如以下:
- #include <fcntl.h> /* For O_* constants */
- #include <sys/stat.h> /* For mode constants */
- #include <semaphore.h>
- #include <stdio.h>
- void print(sem_t *print1, sem_t *print2)
- {
- int i = 0;
- while(1)
- {
- sem_wait(print1);
- i++;
- printf("int print1 i = %d\n", i);
- sem_post(print2);
- }
- }
- int main(int argc, char **argv)
- {
- sem_t *print1, *print2;
- print1 = sem_open("sem_print1", O_CREAT, 0777, 0);
- if(SEM_FAILED == print1)
- {
- perror("sem_open");
- }
- print2 = sem_open("sem_print2", O_CREAT, 0777, 1);
- if(SEM_FAILED == print2)
- {
- perror("sem_open");
- }
- print(print1, print2);
- return 0;
- }
print2.c 代码例如以下:
- #include <fcntl.h> /* For O_* constants */
- #include <sys/stat.h> /* For mode constants */
- #include <semaphore.h>
- #include <stdio.h>
- void print(sem_t *print1, sem_t *print2)
- {
- int i = 0;
- while(1)
- {
- sem_wait(print2);
- i++;
- printf("in print2 i = %d\n", i);
- sleep(1);
- sem_post(print1);
- }
- }
- int main(int argc, char **argv)
- {
- sem_t *print1, *print2;
- print1 = sem_open("sem_print1", O_CREAT, 0777, 0);
- if(SEM_FAILED == print1)
- {
- perror("sem_open");
- }
- print2 = sem_open("sem_print2", O_CREAT, 0777, 1);
- if(SEM_FAILED == print2)
- {
- perror("sem_open");
- }
- print(print1, print2);
- return 0;
- }
删除有名信号量演示样例代码例如以下:
- #include <semaphore.h>
- #include <stdio.h>
- void sem_del(char *name)
- {
- int ret;
- ret = sem_unlink(name);
- if(ret < 0)
- {
- perror("sem_unlink");
- }
- }
- int main(int argc, char **argv)
- {
- sem_del("sem_print1"); //删除信号量文件sem_print1
- sem_del("sem_print2"); //删除信号量文件sem_print2
- return 0;
- }
makefile 代码例如以下:
- all:
- gcc sem_del.c -o sem_del -lpthread
- gcc print1.c -o print1 -lpthread
- gcc print2.c -o print2 -lpthread
- clean:
- rm sem_del print1 print2
执行程序时。先把有名信号量删除(sem_del)。再分别执行 print1 和 print2:
转自:http://blog.csdn.net/tennysonsky/article/details/46500417
进程同步与相互排斥:POSIX有名信号量的更多相关文章
- 一起talk C栗子吧(第一百回:C语言实例--使用信号量进行进程间同步与相互排斥一)
各位看官们.大家好,上一回中咱们说的是进程间同步与相互排斥的样例,这一回咱们说的样例是:使用信号量进行进程间同步与相互排斥. 闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,信号量是由著名 ...
- 多线程相互排斥--mutex(二)
不知道大家对多线程或多进程间的同步相互排斥的控制机制了解的怎么样,事实上有非常多种方法能够实现这个目的,可是这些方法事实上由4种最主要的方法实现.这4种最主要的方法详细定义例如以下:在这有讲得不正确的 ...
- android NDK编程:使用posix多线程与mutex相互排斥同步
MainActivity.java 调用原生方法 posixThreads(int threads, int iterations) 启动线程 package com.apress.threads; ...
- Linux互斥和同步应用程序(一):posix线程和线程之间的相互排斥
[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet 或 .../gentleliu,文章仅供学习交流.请勿用于商业用途] 有了进程的概念,为何还要使用线程呢? 首先,回 ...
- Linux相互排斥与同步应用(三):posix线程实现单个生产者和单个消费者模型
[版权声明:尊重原创.转载请保留出处:blog.csdn.net/shallnet 或 .../gentleliu.文章仅供学习交流,请勿用于商业用途] 在第一节说到了 ...
- Linux同步与相互排斥应用(零):基础概念
[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet 或 .../gentleliu,文章仅供学习交流,请勿用于商业用途] 当操作系统进入多道批处理系统时 ...
- Linux下进程的同步相互排斥实例——生产者消费者
linux下的同步和相互排斥 Linux sync_mutex 看的更舒服点的版本号= = https://github.com/Svtter/MyBlog/blob/master/Linux/pth ...
- 【C/C++多线程编程之六】pthread相互排斥量
多线程编程之线程同步相互排斥量 Pthread是 POSIX threads 的简称,是POSIX的线程标准. Pthread线程同步指多个线程协调地,有序地同步使用共享 ...
- Linux程序设计学习笔记----多线程编程线程同步机制之相互排斥量(锁)与读写锁
相互排斥锁通信机制 基本原理 相互排斥锁以排他方式防止共享数据被并发訪问,相互排斥锁是一个二元变量,状态为开(0)和关(1),将某个共享资源与某个相互排斥锁逻辑上绑定之后,对该资源的訪问操作例如以下: ...
随机推荐
- 全3D模具设计自动化解決方案
- git分支拉取
假设你已经配置好了各种SSH Key之类并熟悉基本的git创建分支.提交分支命令.比如共有2个分支,自己在一台未配置origin电脑上想要拉取某个分支(dev)到本地.步骤如下:1.新建git项目 与 ...
- java.lang.RuntimeException: java.lang.NullPointerException...的错误
先FQ,让电脑能登上谷歌,然后重新安装,应该就好了,我的是这样解决的.如果下次安装又报:java.lang.RuntimeException: java.lang.NullPointerExcepti ...
- Linux系统的启动流程
Linux系统的启动流程: 1.通电(通常按下电源键,开始通电) 2.加载BIOS (通常看到显示器提示按F2进入主板) 3.读取MBR (MBR硬盘的入口地址,用来装载引导) 4.进入引导 (通常有 ...
- day21-2 类的派生
目录 类的派生 派生方法一 派生方法二 类的派生 派生:子类中新定义属性的这个过程叫做派生 派生方法一 指明道姓访问某一个类的函数:该方法与继承无关 class People: def __init_ ...
- 梦想CAD控件网页版标注样式
增加标注样式 _DMxDrawX::AddDimStyle 增加一个新的标注样式,如果当前已经有指定名的标注样式,就直接失败返回.详细说明如下: 参数 说明 BSTR pszName 新增加的标注样式 ...
- 梦想iOS版CAD控件2018.11.07更新
下载地址: http://www.mxdraw.com/ndetail_10110.html 1. 增加iOS上的CAD绘图接口和使用例子 2. 增加动态交互使用例子 3. 把Android上改 ...
- 出现For input string: "" 错误
然后是因为后台生成的是一个数组,前台取的是一个对象,所以会产生这个错误 前后台交互时 mv.addObject("vo1",fhList.get(0));}将数组改成fhList. ...
- NOIP 2018 真・退役记
目录 NOIp 2018 真・退役记 7.01 7.05 \(summary\) 7.12 7.18 7.26 - 7.27 8.2 8.3 8.3 8.7 8.9 8.20 8.24 8.27 8. ...
- [luogu3067 USACO12OPEN] 平衡的奶牛群
传送门 Solution 折半搜索模板题 考虑枚举每个点在左集合和右集合或者不在集合中,然后排序合并即可 Code //By Menteur_Hxy #include <cmath> #i ...