十八、Linux系统编程-信号(五)sigaction和sigqueue

一、sigaction函数
函数声明:
#include <signal.h>
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
函数参数:
  • 该函数的第一个参数为信号的值,可以为除SIGKILL及SIGSTOP外的任何一个特定有效的信号(为这两个信号定义自己的处理函数,将导致信号安装错误)
  • 第二个参数是指向结构sigaction的一个实例的指针,在结构sigaction的实例中,指定了对特定信号的处理,可以为空,进程会以缺省方式对信号处理
  • 第三个参数oldact指向的对象用来保存原来对相应信号的处理,可指定oldact为NULL。
sigaction结构体:
struct sigaction {
    void     (*sa_handler)(int);
    void     (*sa_sigaction)(int, siginfo_t *, void *);
    sigset_t   sa_mask;
    int        sa_flags;
    void     (*sa_restorer)(void);
};
sigaction中的sa_mask会加入到调用进程的进程屏蔽字。 屏蔽的信号到达后将阻塞直到注册的信号处理函数执行完成。
和sigprocmask指定的掩码不同的是,sigprocmask屏蔽的信号在根本上被阻塞,和信号处理函数有没有执行完成没有关系。

返回值:成功返回0,失败返回-1

示例:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#define ERR_EXIT(m) \
        do \
        { \
                perror(m); \
                exit(EXIT_FAILURE); \
        }while(0)
void handle(int sig);
__sighandler_t my_signal(int,__sighandler_t);
int main(int argc,char* argv[])
{
        //my_signal(SIGINT,handle);
        struct sigaction act;
        act.sa_handler = handle;
        sigemptyset(&act.sa_mask);
        act.sa_flags = 0;
        sigaddset(&act.sa_mask,SIGINT);
        if (sigaction(SIGINT,&act,NULL) < 0)
                ERR_EXIT("sigaction error");
        for(;;)
                pause();
        return 0;
}
//implement own signal
__sighandler_t my_signal(int sig,__sighandler_t handler)
{
        struct sigaction act;
        struct sigaction oldact;
        act.sa_handler = handler;
        sigemptyset(&act.sa_mask);
        act.sa_flags = 0;
        if (sigaction(sig,&act,&oldact) < 0)
                return SIG_ERR;
        return oldact.sa_handler;
}

void handle(int sig)
{
        printf("recv a sig=%d\n",sig);
        sleep(3);
}

二、sigqueue函数
功能: 新的发送信号系统调用 , 主要是针对实时信号提出的支持信号带有参数 , 与函数 sigaction () 配合使用
函数声明:
#include <signal.h>
int sigqueue(pid_t pid, int sig, const union sigval value);
函数参数:
进程号,信号,传递的数据
返回值:
成功返回0,失败返回-1

示例:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#define ERR_EXIT(m) \
        do \
        { \
                perror(m); \
                exit(EXIT_FAILURE); \
        }while(0)
void handle(int sig,siginfo_t *,void *);
int main(int argc,char* argv[])
{
        //my_signal(SIGINT,handle);
        struct sigaction act;
        act.sa_sigaction = handle;
        sigemptyset(&act.sa_mask);
        act.sa_flags = SA_SIGINFO;
        if (sigaction(SIGINT,&act,NULL) < 0)
                ERR_EXIT("sigaction error");
        for(;;)
                pause();
        return 0;
}

void handle(int sig,siginfo_t *info,void *ctx)
{
        printf("recv a sig=%d\n",sig);
        printf("recv value=%d\n",info->si_value.sival_int);
        sleep(3);
}<span style="font-family: Arial, Helvetica, sans-serif;"></span>

信号发送:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#define ERR_EXIT(m) \
        do \
        { \
                perror(m); \
                exit(EXIT_FAILURE); \
        }while(0)
int main(int argc,char* argv[])
{
        if (argc != 2)
        {
                printf("usage:should 2 para\n");
        }
        union sigval va;
        va.sival_int = 100;
        sigqueue(atoi(argv[1]),SIGRTMIN,va);
        return 0;
}
通过在短时间内发送多个SIGRTMIN信号,也能证明可靠信号是支持排队的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值