进程间通信之信号he信号量

信号的篇幅较少,就把他和信号量放在一起了。先讲讲他们之间的区别:
1.信号:(signal)是一种处理异步事件的方式。信号时比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程外,还可以发送信号给进程本身。linux除了支持unix早期的信号语义函数,还支持语义符合posix.1标准的信号函数sigaction。

2.信号量:(Semaphore)进程间通信处理同步互斥的机制。是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。

信号:
使用信号要先知道有哪些信号,在Linux下有31个需要记住的通用信号,篇幅限制,这里就不赘述了。
signal:

#include <stdio.h>
#include <signal.h>// 信号处理函数
void handle(int signum)
{printf ("捕捉到一个信号 %d\n", signum);
}int main()
{signal(SIGINT, handle);signal(SIGTERM, handle);while (1);return 0;
}

kill:

#include <stdio.h>
#include <signal.h>int main()
{//while (1){kill (pid, sig);sleep(1);}return 0;
}

alarm:

#include <stdio.h>
#include <signal.h>// 信号处理函数
void handle(int signum)
{printf ("hello world\n");// 定时器重置alarm(2);
}int main()
{// 定时器是一次性的alarm(2);signal(SIGALRM, handle);while (1);return 0;
}

sigaction:

#include <stdio.h>
#include <signal.h>// 信号处理函数
void handle(int signum)
{printf ("hello world\n");// 定时器重置alarm(2);
}int main()
{// 定时器是一次性的alarm(2);struct sigaction act;act.sa_handler = handle;sigaction(SIGALRM, &act, NULL);while (1);return 0;
}

处理子进程的退出:

#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>// 信号处理函数
void handle(int signum)
{while (waitpid (-1, NULL, WNOHANG) > 0){printf ("捕获一个子进程\n");}printf ("111111\n");
}int main()
{signal (SIGCHLD, handle);int count = 10;while (count--){pid_t pid = fork(); switch (pid){case -1:perror ("fork");break;case 0: // 子进程printf ("我是子进程,我的Id 是%d\n", getpid());sleep(1);exit(0);default: // 父进程printf ("我是父进程,Id = %d\n", getpid());break;}}while (1);return 0;
}

信号量

一、什么是信号量

为了防止出现因多个程序同时访问一个共享资源而引发的一系列问题,我们需要一种方法,它可以通过生成并使用令牌来授权,在任一时刻只能有一个执行线程访问代码的临界区域。临界区域是指执行数据更新的代码需要独占式地执行。而信号量就可以提供这样的一种访问机制,让一个临界区同一时间只有一个线程在访问它,也就是说信号量是用来调协进程对共享资源的访问的。

信号量是一个特殊的变量,程序对其访问都是原子操作,且只允许对它进行等待(即P(信号变量))和发送(即V(信号变量))信息操作。最简单的信号量是只能取0和1的变量,这也是信号量最常见的一种形式,叫做二进制信号量。而可以取多个正整数的信号量被称为通用信号量。这里主要讨论二进制信号量。

二、信号量的工作原理

由于信号量只能进行两种操作等待和发送信号,即P(sv)和V(sv),他们的行为是这样的:
P(sv):如果sv的值大于零,就给它减1;如果它的值为零,就挂起该进程的执行
V(sv):如果有其他进程因等待sv而被挂起,就让它恢复运行,如果没有进程因等待sv而挂起,就给它加1.

举个例子,就是两个进程共享信号量sv,一旦其中一个进程执行了P(sv)操作,它将得到信号量,并可以进入临界区,使sv减1。而第二个进程将被阻止进入临界区,因为当它试图执行P(sv)时,sv为0,它会被挂起以等待第一个进程离开临界区域并执行V(sv)释放信号量,这时第二个进程就可以恢复执行。

三、Linux的信号量机制

Linux提供了一组精心设计的信号量接口来对信号进行操作,它们不只是针对二进制信号量,下面将会对这些函数进行介绍,但请注意,这些函数都是用来对成组的信号量值进行操作的。它们声明在头文件sys/sem.h中。
1、semget函数
它的作用是创建一个新信号量或取得一个已有信号量,原型为:

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

第一个参数key是整数值(唯一非零),不相关的进程可以通过它访问一个信号量,它代表程序可能要使用的某个资源,程序对所有信号量的访问都是间接的,程序先通过调用semget函数并提供一个键,再由系统生成一个相应的信号标识符(semget函数的返回值),只有semget函数才直接使用信号量键,所有其他的信号量函数使用由semget函数返回的信号量标识符。如果多个程序使用相同的key值,key将负责协调工作。

第二个参数num_sems指定需要的信号量数目,它的值几乎总是1。

第三个参数sem_flags是一组标志,当想要当信号量不存在时创建一个新的信号量,可以和值IPC_CREAT做按位或操作。设置了IPC_CREAT标志后,即使给出的键是一个已有信号量的键,也不会产生错误。而IPC_CREAT | IPC_EXCL则可以创建一个新的,唯一的信号量,如果信号量已存在,返回一个错误。

semget函数成功返回一个相应信号标识符(非零),失败返回-1.

2、semop函数
它的作用是改变信号量的值,原型为:

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

sem_id是由semget返回的信号量标识符,sembuf结构的定义如下:

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 semum结构,定义如下:

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

前两个参数与前面一个函数中的一样,command通常是下面两个值中的其中一个
SETVAL:用来把信号量初始化为一个已知的值。p 这个值通过union semun中的val成员设置,其作用是在信号量第一次使用前对它进行设置。
IPC_RMID:用于删除一个已经无需继续使用的信号量标识符。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/448453.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开源当自强:我们不是“便宜货”

之前人们争相使用开源软件&#xff0c;无非是因为它便宜、好用、易得&#xff0c;不过根据最新的开源软件调查显示&#xff0c;人们使用开源软件最主要的原因还是看重它的高质量。 成本低是很过公司参与开源项目的最主要原因之一&#xff0c;而现在他们视开源是一条通往创新、省…

前端学习:Vue.js基本使用

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 Vue教程文档&#xff1a; https://cn.vuejs.org/v2/guide/ 定义 实例&#xff1a; new Vue() 挂载点: el 数据&#xff1a;data 模…

PWE

Obstacle Override Logic The obstacle override logic provides the possibility to override obstacle within a window movement by selective switching off the anti-trap functionality.转载于:https://www.cnblogs.com/dannykong/p/11151813.html

进程间通信之消息队列

一、什么是消息队列 unix早期通信机制之一的信号能够传送的信息量有限&#xff0c;管道则只能传送无格式的字节流&#xff0c;这无疑会给应用程序开发带来不便。消息队列&#xff08;也叫做报文队列&#xff09;则克服了这些缺点。 消息队列就是一个消息的链表。可以把消息看…

“ 愿我如星君如月,夜夜流光相皎洁 ...”

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 永远相信爱情 ... 从一而终 ... --------------------------------------------------------------------------- 后记&#xff1a;2…

python内建函数和工厂函数的整理

内建函数参阅&#xff1a; https://www.cnblogs.com/pyyu/p/6702896.html 工厂函数&#xff1a; 本篇博文比较粗糙&#xff0c;后续会深入整理转载于:https://www.cnblogs.com/qiang-upc/p/11155786.html

显卡天梯图:2014最新显卡性能天梯图

随着电脑游戏的推广&#xff0c;很多用户都喜欢上了电脑网络游戏&#xff0c;所以组装电脑用户在装机的时候&#xff0c;会考虑电脑配置的游戏性能&#xff0c;要提高电脑配置游戏性能首要条件就是显卡性能要强&#xff0c;如果显卡性能不佳&#xff0c;那么其它方面性能再强&a…

进程间通信之分别用共享内存和信号量实现卖票

利用共享内存实现的卖票系统&#xff1a; 利用flag来保证同一时间只有一个程序使用内存&#xff0c;使用结束还原。 #include <stdio.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h> #include <string.h> #include <…

shiro 的 @RequiresPermissions 注解使用

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 权限控制是shiro最核心的东西 Shiro权限声明通常是使用以冒号分隔的表达式。一个权限表达式可以清晰的指定资源类型&#xff0c;允许的…

【显卡天梯图】2014年最新显卡天梯图 – 【迄今最全系列显卡】

【显卡天梯图】2014年最新显卡天梯图 – 【迄今最全系列显卡】 随着电脑游戏的推广&#xff0c;很多用户都喜欢上了电脑网络游戏&#xff0c;所以组装电脑用户在装机的时候&#xff0c;会考虑电脑配置的游戏性能&#xff0c;要提高电脑配置游戏性能首要条件就是显卡性能要强&am…

原理系列:Spark1.x 生态圈一览

Spark生态圈&#xff0c;也就是BDAS&#xff08;伯克利数据分析栈&#xff09;&#xff0c;是伯克利APMLab实验室精心打造的&#xff0c;力图在算法&#xff08;Algorithms&#xff09;、机器&#xff08;Machines&#xff09;、人&#xff08;People&#xff09;之间通过大规模…

SpringMVC 注解 : @ModelAttribute

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 SpringMVC 注解 &#xff1a; ModelAttribute 的用法如上。 转自&#xff1a;https://blog.csdn.net/lovesomnus/article/details/78873…

网络编程项目(聊天室项目)

一、实现目标 一个在Linux下可以使用的聊天软件&#xff0c;要求至少实现如下功能&#xff1a; 1. 采用Client/Server架构 2. Client A 登陆聊天服务器前&#xff0c;需要注册自己的ID和密码 3. 注册成功后&#xff0c;Client A 就可以通过自己的ID和密码登陆聊天服务器 4…

CPU天梯图:2014年最新CPU性能天梯图

用户在组装电脑的前期需要考虑怎么选择适合自己的CPU&#xff0c;现在CPU性能强的比较贵&#xff0c;便宜的CPU性能又比较差&#xff0c;选择性价比高并且适合自己的处理器还真是比较花心思。在2014年的时候&#xff0c;最主流热门的AMD处理器是AMD A10-6800K&#xff0c;最新推…

解决: idea 修改 jsp 后,页面刷新无效

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 idea 修改 jsp 后浏览器访问无效。 解决&#xff1a;进入 idea 配置 修改部署方式&#xff1a; 修改 更新文件方式&#xff1a; OK了。

Python中的getpass模块

getpass模块用于输入密码时&#xff0c;隐藏密码字符 代码 import getpass name input("请输入你的名字&#xff1a;") passwd getpass.getpass("请输入你的密码&#xff1a;")print (name,passwd)   首先我们要import引入getpass模块&#xff0c;然后…

C++之命名空间

为什么要使用命名空间&#xff1f; 一个中大型软件往往由多名程序员共同开发&#xff0c;会使用大量的变量和函数&#xff0c;不可避免地会出现变量或函数的命名冲突。当所有人的代码都测试通过&#xff0c;没有问题时&#xff0c;将它们结合到一起就有可能会出现命名冲突。 …

如何做到每天写代码?

摘要&#xff1a;总有一大堆事情没有做完&#xff0c;没有时间和精力为业余项目写代码&#xff1f;不要着急&#xff0c;看看可汗学院计算机科学院院长John Resig怎么说。本文将教你如何保证在每天都能有时间给业余项目写代码。 你是否曾为业余项目没有进展而惆怅过&#xff1f…

Vue 实现前后端分离项目

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 Vue实现前后端分离项目的初体验 经过之前学习的Vue的知识&#xff1a; vue基本指令vue组件vue-resourcevue路由 其实我们已经可以开始…

C++对C的一些加强和变化

实用性加强&#xff1a; int main() {// C语言中的变量都必须在作用域开始的位置定义&#xff01;&#xff01;// C中更强调语言的“实用性”&#xff0c;所有的变量都可以在需要使用时再定义。for (int i 0; i < 10; i){std::cout << i << std::endl;}return…