Linux信号量详解

1.什么是信号量
信号量是一种特殊的变量,访问具有原子性。
只允许对它进行两个操作:
1)等待信号量
当信号量值为0时,程序等待;当信号量值大于0时,信号量减1,程序继续运行。
2)发送信号量
将信号量值加1。

我们使用信号量,来解决进程或线程间共享资源引发的同步问题。

2.Linux中信号量的使用
Linux提供了一组信号量API,声明在头文件sys/sem.h中。
1)semget函数:新建信号量

int semget(key_t key,int num_sems,int sem_flags);

key:信号量键值,可以理解为信号量的唯一性标记。
num_sems:信号量的数目,一般为1
sem_flags:有两个值,IPC_CREATE和IPC_EXCL,
IPC_CREATE表示若信号量已存在,返回该信号量标识符。
IPC_EXCL表示若信号量已存在,返回错误。

返回值:相应的信号量标识符,失败返回-1

2)semop函数:修改信号量的值

int semop(int sem_id,struct sembuf *sem_opa,size_t num_sem_ops);

sem_id:信号量标识符
sem_opa:结构如下

struct sembuf{  short sem_num;//除非使用一组信号量,否则它为0  short sem_op;//信号量在一次操作中需要改变的数据,通常是两个数,一个是-1,即P(等待)操作,  //一个是+1,即V(发送信号)操作。  short sem_flg;//通常为SEM_UNDO,使操作系统跟踪信号,  //并在进程没有释放该信号量而终止时,操作系统释放信号量
}; 

3)semctl函数:用于信号量的初始化和删除

int semctl(int sem_id,int sem_num,int command,[union semun sem_union]);

command:有两个值SETVAL,IPC_RMID,分别表示初始化和删除信号量。
sem_union:可选参数,结构如下:

union semun{  int val; struct semid_ds *buf;  unsigned short *arry;
}; 

一般用到的是val,表示要传给信号量的初始值。

3.Linux信号量使用示例
下例中,我们写了一个程序,程序中有一个char类型的字符,char message='x'
然后同时运行这个程序的两个实例。
第一个实例,带一个参数,将参数的第一个字符赋给message,比如为'0'
第二个实例,使用默认message值'x'
我们的目的是,使用信号量,循环执行这两个实例,
我们可以看到执行结果应该是'x0x0x0x0x0x0'

#include<stdio.h>
#include<stdlib.h>
#include<sys/sem.h>
union semun
{int val;struct semid_ds *buf;unsigned short *array;
};
int sem_id;
int set_semvalue()
{union semun sem_union;    sem_union.val = 1;if(semctl(sem_id,0,SETVAL,sem_union)==-1)return 0;return 1;
}
int semaphore_p()
{struct sembuf sem_b;sem_b.sem_num = 0;sem_b.sem_op = -1;sem_b.sem_flg = SEM_UNDO;if(semop(sem_id,&sem_b,1)==-1){fprintf(stderr,"semaphore_p failed\n");return 0;}return 1;
}
int semaphore_v()
{struct sembuf sem_b;sem_b.sem_num = 0;sem_b.sem_op = 1;sem_b.sem_flg = SEM_UNDO;if(semop(sem_id,&sem_b,1)==-1){fprintf(stderr,"semaphore_v failed\n");return 0;}return 1;
}
void del_semvalue()
{//删除信号量
    union semun sem_union;if(semctl(sem_id,0,IPC_RMID,sem_union)==-1)fprintf(stderr,"Failed to delete semaphore\n");
}
int main(int argc,char *argv[])
{char message = 'x';//创建信号量sem_id = semget((key_t)1234,1,0666|IPC_CREAT);if(argc>1){//初始化信号量if(!set_semvalue()){fprintf(stderr,"init failed\n");exit(EXIT_FAILURE);}//参数的第一个字符赋给messagemessage = argv[1][0];}int i=0;for(i=0;i<5;i++){//等待信号量if(!semaphore_p())exit(EXIT_FAILURE);printf("%c",message);fflush(stdout);sleep(1);//发送信号量if(!semaphore_v())exit(EXIT_FAILURE);sleep(1);}printf("\n%d-finished\n",getpid());if(argc>1){//退出前删除信号量
        del_semvalue();}exit(EXIT_SUCCESS);
}

输出结果:

Linux信号量详解相关推荐

  1. Linux系统结构 详解

    Linux系统结构 详解 标签: 产品产品设计googleapple互联网 2011-01-07 14:14 31038人阅读 评论(6) 收藏 举报 分类: Linux(21) 版权声明:本文为博主 ...

  2. linux /proc 详解

    linux /proc 详解 本文整理了一下 linux /proc下的几个常用的目录和文件,可供查阅,之后在学习工作中有别的用到的话会再补充. /proc 简介 Linux系统上的/proc目录是一 ...

  3. Linux: 系统结构详解

    Linux系统一般有4个主要部分: 内核.shell.文件系统和应用程序.内核.shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序.管理文件并使用系统.部分层次结构如图1-1所 ...

  4. 云计算概念及Linux系统详解

    云计算概念及linux系统详解 先来看一下维基百科上的定义: 云计算是一种按使用量付费的模式,这种模式提供可用的.便捷的.按需的网络访问,进入可配置的网络.服务器.存储.应用软件.服务等能够被快速提供 ...

  5. Linux 系统结构详解——新手上路

    Linux 系统结构详解 Linux系统一般有4个主要部分: 内核.shell.文件系统和应用程序.内核.shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序.管理文件并使用系统 ...

  6. Linux系统调用详解(实现机制分析)

    为什么需要系统调用   linux内核中设置了一组用于实现系统功能的子程序,称为系统调用.系统调用和普通库函数调用非常相似,只是系统调用由操作系统核心提供,运行于内核态,而普通的函数调用由函数库或用户 ...

  7. 《Linux命令详解手册》——Linux畅销书作家又一力作

    关注IT,更要关心IT人,让系统管理员以及程序员工作得更加轻松和快乐.鉴于此, 图灵公司引进了国外知名出版社John Wiley and Sons出版的Fedora Linux Toolbox: 10 ...

  8. Linux系统详解 系统的启动、登录、注销与开关机

    Linux系统详解 第六篇:系统的启动.登录.注销与开关机 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://johncai.blo ...

  9. 每天一个linux命令(25):linux文件属性详解

    每天一个linux命令(25):linux文件属性详解 Linux 文件或目录的属性主要包括:文件或目录的节点.种类.权限模式.链接数量.所归属的用户和用户组.最近访问或修改的时间等内容.具体情况如下 ...

  10. c linux time微秒_学习linux,看这篇1.5w多字的linux命令详解(6小时讲明白Linux)

    用心分享,共同成长 没有什么比每天进步一点点更重要了 本篇文章主要讲解了一些linux常用命令,主要讲解模式是,命令介绍.命令参数格式.命令参数.命令常用参数示例.由于linux命令较多,我还特意选了 ...

最新文章

  1. 简单的Writer和Reader
  2. VS2010水晶报表的添加与使用
  3. iOS开发-NSString去掉所有换行及空格
  4. Mac下github的使用
  5. ejb 2.0 3.0_定义EJB 3.1视图(本地,远程,无接口)
  6. pycharm不同py文件共享参数_PyCharm安装笔记
  7. 从上云到云原生,如何用新技术应对突发事件?
  8. python读取文件编码错误_Python 读取文本文件编码错误解决方案(未知文本文件编码情况下解决方案)...
  9. Linux运维课程 第一阶段 重难点摘要(一)网络基础
  10. Ubuntu18.04 安装 nvidia2080Ti显卡驱动
  11. 改变计算技术的9个伟大算法
  12. java Comparable 和 Cloneable接口
  13. Hibernate中的HQL语言
  14. 线性变换与矩阵的一一映射
  15. VB基础知识之Do...Loop循环
  16. 苹果iPad OS 16原生壁纸Mac动态桌面
  17. 如何设计一个API快速开发平台?
  18. Spark Bloom Filter 测试
  19. idea从零到精通02之idea基础设置
  20. Xib文件使用(一)——xib文件解析

热门文章

  1. android studio日记本源代码,效能日记本——随时回味过往点滴
  2. Maven -- dependency详解
  3. Tomcat8卸载+重装
  4. Ubuntu20.04 安装微信
  5. 31个工作习惯(转)
  6. C语言程序设计基础练习
  7. 简明Python教程链接
  8. MATLAB 工具箱傻瓜式求解 NS(Navier Stoke)方程
  9. 数据结构(C++版)- 教学视频+配套资源
  10. 给还在迷茫的你分享我从零基础的日语文科生半路出家搞Python如何上岸的