Linux 进程通信之 ——信号和信号量总结
如今最经常使用的进程间通信的方式有:信号,信号量,消息队列,共享内存。
所谓进程通信,就是不同进程之间进行一些"接触",这种接触有简单,也有复杂。机制不同,复杂度也不一样。通信是一个广义上的意义,不仅仅指传递一些massege。他们的用法是基本相同的,所以仅仅要掌握了一种的用法,然后记住其他的用法就能够了。
1. 信号
在我学习的内容中,主要接触了信号来实现同步的机制,据说信号也能够用来做其他的事
情,可是我还不知道做什么。
信号和信号量是不同的,他们尽管都可用来实现同步和相互排斥,但前者是使用信号处理器来
进行的,后者是使用P,V*作来实现的。
使用信号要先知道有哪些信号,在Linux下有31个须要记住的通用信号,据说也是system
V中最经常使用的那些。这里略。
1. 1信号相关函数:
#include
int sigaction(int signo, const struct sigaction *act, struct sigaction
*oact);
该函数用来为进程安装信号处理器,struct sigaction数据是用来保存信号处理器的相
关信息。
#include
int sigemptyset(sigset_t *set);
将信号集合清空。
int sigfillset(sigset_t *set);
将信号集合设置成包括全部的信号。在对信号进行*作曾经一定要对信号集进行初始化。
int sigaddset(sigset_t *set, int signo);
向信号集中加入signo相应的新信号。
int sigdelset(sigset_t *set, int signo);
从信号集中删除signo相应的一个信号。
int sigismember(const sigset_t *set, int signo);
推断某个信号是否在信号集中。返回1则在,0则不在。
#include
int sigprocmask(int how,const sigset_t *set, sigset_t *oset);
用来设置进程的信号屏蔽码。信号屏蔽码能够用来在某段时间内堵塞一些信号集中的信
号,假设信号不在信号集中,就不必讨论它,由于肯定不响应,能否生成也不肯定,我
没有做过试验。
1.2我所理解的使用信号机制的方法:
使用信号,主要做的事情就是信号处理器的工作,这里面是你想做的事情。就像中断处理
函数一样。
在使用信号曾经,首先要初始化信号集,仅仅有在信号集里面的信号才会被考虑。
有两种方法能够初始化信号集,一种是设置空信号集,一种是将全部的信号都加到信号集
中。假设你自己想要的信号集不是这两种,能够在初始化了以后通过加入和删除信号进行
定制。
假设在进程运行的一段时间内不想对某些信号进行响应,则能够使用sigprocmask对当前
的信号集中的一些信号进行堵塞,稍后再运行。
当你将信号集设置完成后,在让他工作之前须要安装信号处理器。安装信号处理器能够实
现这几个功能:
指定信号处理函数的入口;指定信号屏蔽集合;指定信号处理器的一些标志。所谓信号处
理器,就是指定了一些处理方法,关键在于安装信号处理器,这是使正确的信号进行正确
的处理关键。在安装的时候,一定要对特定的信号赋予正确的信号处理函数。
我不知道不同进程之间的信号处理器能否混用,可是像一个特定的进程中有多少个信号处
理器这种问题是不能提的。由于信号处理器是一个概念,他针对的是信号,就是说假设
你指定了一个数据结构,用它来存储针对某个信号的处理信息,那么安装信号处理器就是
赋予这个数据结构一些相关信息,使用信号处理器就是用这个数据结构存储的信息来组织
一种机制当发生这个信号的时候会做一些你实现设置好的处理。可是假设区分不同进程中
对同一个信号的不同处理器?我想处理器可能仅仅对核它所属的进程有关的信号进行响应,
可是假设是这种话,那这是怎么实现的呢?
只是有一点是能够知道的,那就是每个信号都有一个信号处理器(确定的),能够动过
安装信号处理器来指定她的行为。信号处理器由他自己的信息存储区域(我不知道在什么
地方),可是能够通过向sigaction类型的数据结构向信号处理器的信息存储区域中传递
信息。这个数据结构由一个就能够了,由于它仅仅是暂时传递数据的载体。
可是sigpromask和信号处理器里面的sigmask是不一样的,前者是在进程当前流程设置信
号屏蔽,后者是指定在信号处理器作用时须要屏蔽掉的信号。比如,在设置某个特定信号
的信号处理器时,我们当然不能让它的信号处理器工作了,由于还没有设置完吗,这是我
们能够使用sigprocmask来让当前的流程開始堵塞该信号,当设置完信号处理器以后,再
用sigprocmask恢复被堵塞的信号。而以后再接收到该信号时,信号处理器就能够工作了。
我的想法是,同一个信号在不同的进程里能够有不同的信号处理器(一般应该有一个缺省
处理),当系统中发生一个信号时,全部能接受到的进程都能够接收到这个信号,并用他
们自己的信号处理器对这个信号做出各自的响应。
1.3怎样用信号来进行进程间的同步
同步的实现主要是通过在接受信号之前挂起进程,等待相关信号。所以涉及到异步信号安
全函数的概念。
只是信号怎样来实现进程间的相互排斥,我理解不是非常多,我想信号的主要用处还是在软中断
处理和进程同步。
2.信号量
信号量和信号是不同的东西,细致想想就能够理解:信号是实现约定的固定的值,而信号
量是一个变量记录着某些特定信息。
信号量这种东西我们在*作系统课程中就已经接触过了,这里仅仅是再草草说几句。信号量
分为有名和无名两种。进程间通信用有名信号量,同一进程内部通信一般用无名信号量。
这个我不再多说。
2.1信号量相关函数
#include
#include
#include
int semget(key_t key, int nsems, int semflg);
创建一个新的信号量组或获取一个已经存在的信号量组。
#include
#include
#include
int semop(int semid, struct sembuf *sop, int nsops);
semop函数能够一次对一个或多个信号量进行*作。
Int semctl(int sem_id, int semnum, int cmd,/*union semun arg*/…);
该函数能够用来获取一些信号量的使用信息或者是来对信号量进行控制。
2.2我对信号量机制的理解
对信号量的*作仅仅有两个:P, V。
为了在逻辑上便于组织信号量,信号量机制中有一个概念是信号量组。我们能够把一个信
号量组中创建相关的信号量,这样逻辑上清楚也便于管理。在使用之前你相同须要对他们
进行初始化:生成或打开信号量组,向当中生成或删除你指定的信号量。
对信号量的*作仅仅用两种,他都是通过semop函数中的sops參数来指定的,假设这个參数
是一个数组的话,那么就是对多个信号量进行*作。Sops參数中的sem_op字段指明了对信
号量进行的是P*作还是V*作。你仅仅要指定即可了,具体的*作不须要你去实现,函数中
都已经提供了。使用信号量,你得清楚信号量组id和信号量在信号量组中的位置(事实上也
就是另一个id)。一个信号量必须属于一个信号量组,否则不能被系统所使用。切记!
信号量和信号量组是不会被系统所自己主动清理的,所以当你的进程退出前,千万别忘了清理
你生成的那些信号量们。
信号量既能够实现相互排斥,也能够实现同步,这里就不说了,*作系统课程中是有介绍的。
3.消息队列
消息队列是比較高级的一种进程间通信方法,由于它真的能够在进程间传送massege,你
传送一个"I seek you"都能够。
一个消息队列能够被多个进程所共享(IPC就是在这个基础上进行的);假设一个进程的
消息太多一个消息队列放不下,也能够用多于一个的消息队列(只是可能管理会比較复
杂)。共享消息队列的进程所发送的消息中除了massege本身外另一个标志,这个标志
能够指明该消息将由哪个进程或者是哪类进程接受。每个共享消息队列的进程针对这个
队列也有自己的标志,能够用来声明自己的身份。
对于系统中的每个消息队列,都有一个数据结构来代表它,这个数据结构是msqid_ds,
这里略去不讲,在中能够看到它的原型。
3.1消息队列相关函数
使用消息队列之前,你要么获得这个消息队列,要么自己建立一个,否则是不能使用消息
队列的(我认为这都像是多余的话,请见谅)。当这个消息队列不再使用时,也一定要有
一个进程来删除消息队列,系统是不会自己主动的清理消息队列和msgid_ds的。
Int msgget(key_t key, int msgflg);
获取一个存在的消息队列的ID,或者是依据跟定的权限创建一个消息队列。可是怎么样去
删除这个消息队列,我还不十分清楚。
Int msgctl(int msqid, int cmd, struct msqid_ds *buf);
用来从msqid_ds中获取非常多消息队列本身的信息。
Int msgsnd(int msqid, void *msgp, size_t msgsz, int msgflg);
用于向队列发送消息。
Int msgrcv(int msqid, void *msgp, size_t msgsz, long int msgtyp, int
msgflg);
从队列中接收消息。
我这个文档里面对消息队列中的一些临界情况所述不多,由于这是我的小结,而非介绍。
在GNU C库技术中能够看到它的具体介绍。
Linux 进程通信之 ——信号和信号量总结的更多相关文章
- linux 进程通信之 信号
一,管道PIPE 二,FIFO通信 三,mmap通信 四,信号的概念 信号的特点:简单,但不能携带大量的信息,满足特定条件就会发生 信号的机制:进程B发送信号给进程A.信号是由内核来处理的. 信号的产 ...
- linux进程通信之信号
本节主要学习信号和与信号相关的处理函数,兴许还会更新. http://blog.csdn.net/xiaoliangsky/article/details/40264151 一 信号 信号是UNIX和 ...
- Linux进程通信----匿名管道
Linux进程通信中最为简单的方式是匿名管道 匿名管道的创建需要用到pipe函数,pipe函数参数为一个数组表示的文件描述字.这个数组有两个文件描 述字,第一个是用于读数据的文件描述符第二个是用于写数 ...
- linux进程通信
e14: 进程间通信(进程之间发送/接收字符串/结构体): 传统的通信方式: 管道(有名管道 fifo,无名管道 pipe) 信号 signal System V(基于IPC的对象): ...
- Linux进程通信学习总结
http://blog.csdn.net/xiaoweibeibei/article/details/6552498 SYSV子系统的相关概念 引用标识符:引用标识符是一个整数,表示每一个SYSV ...
- 【转】如何基于linux进程通信设计方案
前言 linux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的.而对Unix发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在 ...
- Linux进程通信之匿名管道
进程间的通信方式 进程间的通信方式包括,管道.共享内存.信号.信号量.消息队列.套接字. 进程间通信的目的 进程间通信的主要目的是:数据传输.数据共享.事件通知.资源共享.进程控制等. 进程间通信之管 ...
- Linux进程通信的几种方式总结
进程通信的目的 数据传输 一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几M字节之间 共享数据 多个进程想要操作共享数据,一个进程对共享数据 通知事 一个进程需要向另一个或一组进程发 ...
- Python网络编程(进程通信、信号、线程锁、多线程)
什么是进程通讯的信号? 用过Windows的我们都知道,当我们无法正常结束一个程序时, 可以用任务管理器强制结束这个进程,但这其实是怎么实现的呢? 同样的功能在Linux上是通过生成信号和捕获信号来实 ...
随机推荐
- Android 数据库ORM框架GreenDao学习心得及使用总结<二>
转:http://blog.csdn.net/xushuaic/article/details/24496191 第五篇 查询 查询会返回符合某些特定标准的实体.你可以使用原始的SQL定制查询语句,或 ...
- xunsearch安装与卸载
刚接触xunsearch(迅搜)的时候,我是排斥的.排斥的原因不是因为害怕学习新技术(其实我是对心技术很感兴趣),而是因为:一方面xunsearch是国人开发的,对于国人写的开源产品,我不是太感兴趣( ...
- Get请求出现乱码的解决方案
Get请求出现乱码,模拟一般出现的场景.场景一:超链接<a href=”url?name=张三&age=18”>场景二:window.opon(“url?name=张三&a ...
- 多字节字符与界面 manifest
之前把调试项目的时候软件界面变成了很古板的那种界面,后来查了一会发现因为字符集的改变,个人习惯统一我一般用同一种字符集,虽然Unicode只涉及语言问题,不过总感觉它占内存,用非字符集,搜索发现将代码 ...
- UVA1351-----String Compression-----区间DP(记忆化搜索实现)
本文出自:http://blog.csdn.net/dr5459 题目地址: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&a ...
- 开源点评:Protocol Buffers介绍
今天来介绍一下“Protocol Buffers”(下面简称protobuf)这个玩意儿.本来俺在构思“生产者/消费者模式 ”系列的下一个帖子:关于生产者和消费者之间的传输数据格式.因为里面扯到了pr ...
- oracle表设置主键自增长
create or replace table TBL_SYS_USER ( user_id NUMBER(19) not null, user_name ...
- jquery JS 左右方向键
$(function (){ // $(document).keydown(function(e){ var code=e.which; switch (code) { case 38: //上 br ...
- 常用Json
一般Json是页面与页面之间传递使用. Json用途 1 后台与前台数据交互,并且数据较复杂,如果数据单一,直接传递字符串,然后在前台用js分割就行. 2 webservice和html ...
- Nginx启动报错:10013: An attempt was made to access a socket in a way forbidden
Nginx在win7,win2008下启动报错:bind() to 0.0.0.0:80 failed (10013: An attempt was made to access a socket i ...