sigaction和sigqueue

 

sigaction和signal一样用来注册信号处理函数,siqqueue和kill一样,用来发送信号,但是sigaction比signal功能强大,signal比较简单。

 

int sigaction(int signum, const struct sigaction *act, struct sigaction* oldact /*保存老的sigaction*/); 

 

struct sigaciton{

     void (*sa_handler)(int);     // 回调函数

     void (*sa_sigaction)(int, siginfo_t*, void*);     // 回调函数

     sigset_t sa_mask;     // 在信号出发执行回调函数的期间,屏蔽sa_mask所指定的信号

     int sa_flags;     // 为0表示默认行为,设置为SA_RESTART时,被信号打断后,系统调用可以重启

     void (*sa_restorer)(void);     // should not to be use

};

 

void sig_handle(int val, siginfo_t* info, void* p)

{

    printf("sig_handle\n");

}

 

int main()

{

    struct sigaction act;

    act.sa_handler = NULL;

    act.sa_sigaction = sig_handle;

    act.sa_flags = SA_RESTART;

    sigemptyset(&act.sa_mask);

    act.sa_restorer = NULL;

 

    sigaction(SIGINT, &act, NULL);

 

    while (1)

    {

        sleep(1);

    }

    return 0;

}

 

int sigqueue(pid_t pid, int sig, const union sigval value);

 

union sigval{

     int     sigval_int;

     void     *sigval_ptr;

}

 

void sig_handle(int val, siginfo_t* info, void* p)

{

    printf("sig_handle value = %d\n", info->si_int);

}

 

int main()

{

    struct sigaction act;

    act.sa_handler = NULL;

    act.sa_sigaction = sig_handle;

    act.sa_flags = SA_SIGINFO;     // 如果sigqueue要传参数给信号处理函数,这个要设置为SA_SIGINFO;

    sigemptyset(&act.sa_mask);

    act.sa_restorer = NULL;

 

    sigaction(SIGINT, &act, NULL);

 

    pid_t pid = fork();

    if (pid == 0)

    {

        union sigval v;

        v.sival_int = 100;

        sigqueue(getppid(), SIGINT, v);

        return 0;

    }

    while (1)

    {

        sleep(1);

    }

    wait(NULL);

    return 0;

}

 

强大:

  1. 可以传递参数

  2. 可以获得发送信号的进程信息

  3. 可以设置SA_RESTART

> SA_RESTART:

 

void handle(int v, siginfo_t* v1, void* v2)

{

    printf("sig handle\n");

}

 

int main()

{

//  signal(SIGINT, handle);

    struct sigaction act;

    act.sa_handler = NULL;

    act.sa_sigaction = handle;

    sigemptyset(&act.sa_mask);

 

//  设置了restart之后,如果该信号打断了某个系统阻塞调用时,该系统调用会自动重启

//  act.sa_flags = SA_RESTART;

 

    act.sa_flags = 0; // 被打断的系统调用不会重启

    act.sa_restorer = NULL;

 

    sigaction(SIGINT, &act, NULL);     // signal 默认打断了可以重启

 

    char buf[1024];

    int ret;

READAGAIN:

    ret = read(0, buf, sizeof(buf));

    // 阻塞的read被中断打断时,会返回-1

    if(ret < 0)

    {

        if(errno == EINTR)

        {

            printf("read is interrupt by signal\n");   

            goto READAGAIN;

        }

    }

    buf[ret] = 0;

 

    printf("%s\n", buf);

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值