寒假学习 第20天 (linux 高级编程)

寒假学习 第20天 (linux 高级编程) 笔记总结


一、sigqueue/sigaction


1. 信号中断函数是否被其他信号中断?


   信号函数调用中只屏蔽本身信号,不屏蔽其他信号

例子:

#include <stdio.h>
#include <signal.h>

void handle(int s)
{
    printf("start!\n");
    sleep(10); 
    printf("end\n");
}

int main(int argc, const char *argv[])
{
    signal(SIGINT,handle);
    while(1);
    return 0;
}

在sleep()的10秒中内发出SIGINT信号,不会中断,但在这10秒钟发出本身的信号会排队,发送SIGUSR1信号就会退出(SIGUSR1没有注册)


2. 怎样保证函数调用中屏蔽指定的信号呢?


sigaction可以指定处理函数调用的屏蔽信号

sigaction在处理信号的时候,可以就是传递数据


sigqueue在发送信号时候,可以发送数据


sigaction / sigqueue  相当于 signal / kill 的增强版本,且这4个函数可以混合使用(例如sigaction发出的信号signal可以处理等)


使用sigaction / sigqueue有两个理由

     稳定性

     增强功能


函数原型


int sigaction(int signum,   //处理的信号

                     const struct sigaction *act,   //输入的结构体,指定处理函数及其参数
                     struct sigaction *oldact);    //返回原来的处理函数的结构体


struct sigaction {
           void     (*sa_handler)(int);      //传统的信号处理函数
           void     (*sa_sigaction)(int, siginfo_t *, void *);     //信号处理函数,多带了一个传递额外信息的参数,函数第三个参数是保留参数
           sigset_t   sa_mask;     //信号处理函数在处理过程中要屏蔽的信号
           int        sa_flags;    //控制信号是调用结构体中上面第一个函数还是上面第二个函数  SA_SIGINFO 表示使用第二个

           void     (*sa_restorer)(void);    //保留的成员

};


例子:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void handle(int s)
{
    printf("start!\n");
    sleep(10);
    printf("end\n");
}

int main(int argc, const char *argv[])
{
    printf("pid:%d\n",getpid());

    struct sigaction act={0};
    act.sa_handler=handle;
    sigemptyset(&act.sa_mask);
    sigaddset(&act.sa_mask,SIGINT);
    act.sa_flags=0;

    sigaction(SIGUSR1,&act,0);

    while(1);

    return 0;
}
信号处理函数中 SIGUSR1与SIGINT都被屏蔽。

int sigqueue(pid_t pid, int sig, const union sigval value); //value 传递的信息

union sigval {
       int   sival_int;
       void *sival_ptr;
};


例子1:

#include <stdio.h>
#include <signal.h>

int main(int argc, const char *argv[])
{
    union sigval val;
    val.sival_int=333;

    sigqueue(20899,SIGUSR1,val);

    return 0;
}

运行,上上面的代码程序就会收到SIGUSR1的信号


如果把上上面的代码改成下面这样,就可以得到传递的数据

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void handle(int s,siginfo_t* info,void *d)
{
    printf("start!\n");
    printf("info:%d\n",info->si_int);
    sleep(10);
    printf("end\n");
}

int main(int argc, const char *argv[])
{
    printf("pid:%d\n",getpid());

    struct sigaction act={0};
    act.sa_handler=handle;
    sigemptyset(&act.sa_mask);
    sigaddset(&act.sa_mask,SIGINT);
    act.sa_flags=SA_SIGINFO;

    sigaction(SIGUSR1,&act,0);

    while(1);

    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值