Linux 信号 向信号处理函数传递数据

1.Linux 信号是一种异步机制,进程可以接收一个信号,并有相应的处理操作,如果我们需要改变当该信号发生时的默认行为,我们就需要捕捉该信号,并且自己书写信号处理函数。

2.这种信号处理函数就跟中断差不多,当一个进程接收到一个信号时,进程会暂停当前的执行流,转而调用信号处理函数,信号处理函数结束之后,会继续刚才的执行流继续执行。

3.如果进程已经阻塞在一些系统调用的时候,信号发生之后,是不会重新调用这些系统调用的,但是也可以设置成继续进行这些系统调用。

 

我们可以使用sigaction函数来对一个信号进行捕捉,并且指定这个信号的处理函数。这个是POSIX.1标准,如果在不支持POSIX.1的系统上面,那么还是需要调用signal这个标准C函数。

对于信号处理函数是否可以接收参数来说,我们可以把信号处理函数分成两种:一种可以接收用户发送过来的数据,另外一种不能得到用户发送过来的数据。

① 不能接收用户发送过来的数据:

int firstFunc(int signo) {
    printf("In the handler");
}

struct sigaction newAction, oldAction;
memset(&newAction, 0, sizeof(newAction))
newAction.sa_flag = 0;
newAction.sa_handler = firstFunc;
sigemptyset(&sa_mask)
sigaction(SIGINT, &newAction, &oldAction)

这样,当此进程收到SIGINT信号的时候,就会调用firstFunc函数,调用完毕之后会继续主函数的执行流。

② 可以接收用户发送过来的数据:

        有时候我们想在这个信号发生的时候,传递一些我们需要的信息到信号处理函数里面,这个时候我们就需要用另外一种方式:

int secondFunc(int signo, siginfo* info, void* context) {  // (1)
    Data* data = (Data*)info->si_value.sival_ptr;
    /*Deal with data......*/
}

struct sigaction newAction, oldAction;
memset(&newAction, 0, sizeof(newAction))
newAction.sa_flag = SA_SIGINFO;  // (2)
sigemptyset(&newAction.sa_mask);
newAction.sa_sigaction = secondFunc;  // (3)
Data* data;
/*Construct your data struct.*/
union sigval curVal;   
curVal.sival_ptr = (void*)data;
sigqueue(getpid(), SIGINT, curVal);   // (4)

上面需要注意的就是4点:

(1)这个是信号处理函数的原型,多出来了两个参数。只能这样写。

(2)需要在sigaction里面的sa_flag 添加SA_SIGINFO,表示我们会传递一些信息到错误处理函数里面。

(3)使用SA_SIGINFO之后,我们需要使用sa_sigaction这个成员变量,而不是sa_handler。

(4)我们需要使用sigqueue函数来对特定的进程发送特定的信号,并且curVal这个联合体里面携带了我们需要传递的数据的指针。

两种方式需要按照特定的需求来选用。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值