首页 > 编程知识 正文

二进制对称信道的信道容量,在二进制信道中,信源消息

时间:2023-05-05 00:30:05 阅读:36756 作者:2133

信号博文linux进程间通信信号

本文重点说明sigaction、sigqueue两个函数分别用于信号处理函数的注册、信号处理发送函数的是signal和kill的升级版。 一般API信号处理函数的注册

入门版:函数signal

高级版:函数sigaction

信号处理发送函数

1 .入门版:基尔

2 .高级版: sigqueue

入门版的信号处理API侧重于动作,但kill函数发送的信号无法携带数据。

对于高级版信号处理API的重点信号手机的信息

sigaction函数sigaction是一种系统调用,可用于查询和设置信号处理方法。

的头文件#includesignal.h函数原型: intsigaction(intsignum,const struct sigaction *act,struct sigaction *oldact ); signum :参数指示要捕获的信号类型。

act :参数指定新的信号处理方式。 如果结构信号类型不为空,则表示该信号需要新配置。

oldact :备份。 如果不为空,则可以备份以前的信号配置,以便以后轻松恢复。

结构信号结构介绍结构信号{ void (* sa _ handler ) } (int ); //不接受信号处理程序、追加数据。 忽略SIG_IGN,SIG_DFL表示默认行为void(*sa_sigaction((int,siginfo_t *,void * ) ); 能够与sigqueue配合使用sigset_t sa_mask接受附加数据的信号处理程序//块关键字的信号集在调用捕获函数之前将信号添加到块字中,然后将信号捕获函数int sa_flags; //影响信号的行为SA_SIGINFO表示数据被接受}; //回调函数句柄sa_handler和sa_sigaction只能选择sa_handler sa_handler之一。 此参数与signal ()中的参数handler相同,表示新的信号处理函数

void(*sa_sigaction ) (int,siginfo_t *,void * ); void(*sa_sigaction ) (int,siginfo_t *,void * ); 关于以上的处理函数需要再说明一下。

void*是接收到的信号所拥有的附加数据。

结构信号主要适用于记录有关接收信号的信息。

siginfo_t { int si_signo; /* Signal number */int si_errno; /* An errno value */int si_code;/*信号代码*/int si _ trap no;/* trapnumberthatcausedhardware -通用信号(unusedonmostarchitectures ) */pid_t si_pid;/*发送处理程序id */uid _ TSI _ uid;/* realuseridofsendingprocess */intsi _ status;/* exitvalueorsignal */clock _ TSI _ utime;/*用户定制*/clock _ TSI _ stime;/*系统时间咨询*/SIG val _ TSI _ value; /* Signal value */int si_int;/* POSIX.1b信号*/void * si _ ptr;/* POSIX.1 bsignal */intsi _ overrun;/*时间开销计数; POSIX.1b timers */int si_timerid;/*时间id; POSIX.1b timers */void *si_addr;/* memorylocationwhichcausedfault * /

int si_band; /* Band event */ int si_fd; /* File descriptor */}

其中的成员很多,si_signo 和 si_code 是必须实现的两个成员。可以通过这个结构体获取到信号的相关信息。
关于发送过来的数据是存在两个地方的,sigval_t si_value这个成员中有保存了发送过来的信息;
同时,在si_int或者si_ptr成员中也保存了对应的数据。

sa_mask

sa_mask 用来设置在处理该信号时暂时将sa_mask 指定的信号集搁置
sa_mask 成员,设置在其的信号集中的信号,会在捕捉函数调用前设置为阻塞,并在捕捉函数返回时恢复默认原有设置。这样的目的是,在调用信号处理函数时,就可以阻塞默写信号了。在信号处理函数被调用时,操作系统会建立新的信号阻塞字,包括正在被递送的信号。因此,可以保证在处理一个给定信号时,如果这个种信号再次发生,那么他会被阻塞到对之前一个信号的处理结束为止。

sa_flags

sa_flags 用来设置信号处理的其他相关操作,下列的数值可用:
SA_RESETHAND:当调用信号处理函数时,将信号的处理函数重置为缺省值SIG_DFL
SA_RESTART:如果信号中断了进程的某个系统调用,则系统自动启动该系统调用
SA_NODEFER :一般情况下, 当信号处理函数运行时,内核将阻塞该给定信号。但是如果设置了 SA_NODEFER标记, 那么在该信号处理函数运行时,内核将不会阻塞该信号

sigqueue函数

在队列中向指定进程发送一个信号和数据

包含的头文件 #include <signal.h> 函数原型: int sigqueue(pid_t pid, int sig, const union sigval value); union sigval { int sival_int; void *sival_ptr; };

pid:发给谁,是目标进程的进程号
sig:发的是什么信号,是信号代号
value:发送的消息(int或者char*),是一个联合体,表示信号附带的数据,附带数据可以是一个整数也可以是一个指针,有如下形式:

union sigval {int sival_int;void *sival_ptr;//指向要传递的信号参数};value 使用这个函数之前,必须要有几个操作需要完成

1、使用 sigaction 函数安装信号处理程序时,制定了 SA_SIGINFO 的标志。
2、sigaction 结构体中的sa_sigaction成员提供了信号捕捉函数。如果实现的sa_handler成员,那么将无法获取额外携带的数据。
3、sigqueue 函数只能把信号发送给单个进程,可以使用 value 参数向信号处理程序传递整数值或者指针值。
4、、sigqueue 函数不但可以发送额外的数据,还可以让信号进行排队(操作系统必须实现了 POSIX.1的实时扩展),对于设置了阻塞的信号,使用 sigqueue 发送多个同一信号,在解除阻塞时,接受者会接收到发送的信号队列中的信号,而不是直接收到一次。但是,信号不能无限的排队,信号排队的最大值受到SIGQUEUE_MAX的限制,达到最大限制后,sigqueue 会失败,errno 会被设置为 EAGAIN。

实例:

demo.c

#include<stdio.h>#include <signal.h>/*信号处理函数*/void handler(int signum, siginfo_t *info, void *context){ printf("get signum %dn",signum); if(context!=NULL){//如果有内容 printf("get data=%dn",info->si_int); printf("get data=%dn",info->si_value.sival_int); }}int main(){ struct sigaction act; act.sa_sigaction = handler;//信号处理程序,能够接受额外数据和sigqueue配合使用 act.sa_flags = SA_SIGINFO;//影响信号的行为SA_SIGINFO表示能够接受数据 sigaction(SIGUSR1,&act,NULL); sigaction(SIGINT,&act,NULL); while(1); return 0;}

send.c

#include <signal.h>#include <stdio.h>int main(int argc,char **argv){ int pid = atoi(argv[2]); int signum = atoi(argv[1]); union sigval value; value.sival_int = 100; sigqueue(pid,signum,value);//信号处理发送函数 printf("donen"); return 0;} 实验结果:

具体执行过程下图

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。