菜鸟学习历程【20】进程通信(2)

进程通信(2)

信号

信号本质:信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断信号是一样的。信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道到底什么时候到达。

信号来源:信号事件发生有两个来源,硬件来源(比如按下键盘或其他硬件故障);软件来源,最常用发生信号的系统函数是kill,raise,alarm,setitimer及sigqueue函数,软件来源还包括一些非法运算等操作。

分类:
(1)从可靠性方面,分为可靠信号与不可靠信号
(2)从时间方面,可分为实时信号与非实时信号

可靠性信号与不可靠信号

1.不可靠信号:(信号值小于SIGRTMIN)早期的Unix系统中信号机制比较简单和原始,将那些建立在早期机制上的信号称为不可靠信号,信号可能会丢失
2.可靠信号:(信号值介于SIGRTMIN, SIGRTMAX之间)新增了一些信号,这些信号在定义时就定义为可靠信号,这些信号支持排队,不会丢失

信号的可靠与不可靠只与信号值有关,与信号的发送及安装函数有关

实时信号与非实时信号:

早期Unix系统之定义了32种信号,Red Hat 7.2支持64种信号,编号为0—63,前32种信号已经有了预定义值,每个信号有了确定的用途及含义,并且每种信号都有各自的默认动作。
后32种信号表示实时信号,等同于前面阐述的可靠信号,这保证额发送的多个实时信号都被接受。实时信号是POSIX标准的一部分,可用于应用进
程。

非实时信号都不支持排队,都是不可靠信号;实时信号都支持排队,都是可靠信号;

信号的处理方式:

1.忽略信号:对信号不作处理,其中,有两个信号不能忽略,即SIGKILL和SIGSTOP

2.捕捉信号:定义信号处理函数,当信号发生时,执行相应的处理函数

3.执行默认操作:Linux对每种信号都规定了默认操作,注意,进程对实时信号的默认反应是进程终止

信号发送

发生信号的主要函数有:
kill(),raise(),sigqueue(),alarm(),setitimer()和abort()。

1.kill()函数

kill函数用于传送信号给指定的进程

int kill(pid_t pid , int sig);

参数说明:

  • pid > 0 :将信号传给进程识别码为pid的进程
  • pid = 0:将信号传给和目前进程相同进程组的所有进程
  • pid = -1:将信号广播传送给系统内所有的进程
  • pid < 0:将信号传给进程组识别码为pid绝对值的所有进程

返回值:执行成功则返回0,如果有错误则返回-1;

2.alarm()函数

alarm函数用于设置信号传送闹钟

unsigned int alarm(unsigned int seconds);

参数说明:

alarm()用来设置信号SIGALRM,在经过参数seconds指定的秒数后传送给目前的进程。如果参数seconds为0,则之前设置的闹钟会被取消,并将剩下的时间返回。

返回值:

返回之前闹钟剩余的秒数,如果之前未设置闹钟则返回0;

自定义处理信号方式

Linux主要由两个函数来实现信号的安装——signal()和sigaction()。其中,signal()是在可靠信号系统调用的基础上实现的,是库函数,只有两个参数,不支持信号传递信息,主要是用于前32种非实时信号的安装;而sigaction()是较新的函数,有三个参数,支持信号传递信息,主要用来与sigqueue系统调用配合使用,当然sigaction()同样支持非实时信号的安装。

1.signal函数

signal函数用来传送给指定的进程

void(*signal(int signum, void(*handler)(int)))(int);

函数说明:

signal()会议参数signum指定的信号来设置还信号的处理函数,当指定的信号到达时就会跳转到参数handler指定的函数执行;

如果参数handler不是函数指针,则必须是下列两个常量之一:

1.SIG_IGN:忽略参数signum指定的信号
2.SIG_DFL:将参数signum指定的信号重设为核心预设的信号处理方式

返回值:

返回先前的信号处理函数指针,如果有错误则返回SIG_ERR(-1)

2.sigaction函数

sigaction函数用来查询或设置信号处理方式

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

参数说明:

sigaction()会以参数signum指定的信号的编号来设置该信号的处理函数,参数signum可以指定除SIGKILL和SIGSTOP以外的所有信号,如果参数结构sigaction定义如下:

struct sigaction
{
    void (*sa_handler)(int);
    sigset_t sa_mask;
    int sa_flag;
    void (*sa_restorer)(void);
};

消息队列

管道只能传送无格式字节流,能够传送的信号量有限,消息队列(也称为报文队列)则克服了 这些缺点。
消息队列是一个消息的链表,可以把消息看作是一个记录,具有特定的格式。

消息队列的执行步骤大致如下:

1.打开、创建
2.发送信息
3.接受信息
4删除消息队列

下面,我们

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值