Posix实时信号

信号可以分为两大组:

1,其值在SIGRTMIN和SIGRTMAX之间的实时信号。

2,所有其它信号。

接下来有一个参数很关键,那就是接收某个信号的进程的sigaction调用中是否指定了新的SA_SIGINFO标志。

如果此标志指定了,那么实时信号的实时行为有保证,否则事实行为未指定,但对于一般信号来说,无论此标志有无指定,实时行为都未指定。

那什么叫做实时行为呢?

事实行为有如下特征:

1,信号是排队的,同一信号产生了三次,那么它就递交三次。

2,当有多个SIGRTMIN到SIGRTMAX范围内的解阻塞信号排队时,值越小的优先权越高。

3,当某个非实时信号递交时,传递给它的信号处理程序的唯一参数就是该信号的值;但对于实时信号来说,它可以携带更多的信息。例如,通过SA_SIGINFO标志安装的实时信号的信号处理程序声明如下:

void func(int signo, siginfo_t *info, void *content)

typedef struct {
    int si_signo; /*same value as signo argument*/
    int si_code; /*SI_{USER,QUEUE,TIMER,ASYNCIO,MEGEQ}*/
    union sigval si_value; /*integer or pointer value from sender*/
} siginfo_t;

4,一些新的函数定义成使用实时信号工作。例如,sigqueue函数代替kill函数。

上面讲到了si_code值,此值是用来表明此信号是由哪个事件产生的,列表如下:

SI_ASYNCIO:信号是由某个异步I/O请求完成。

SI_MESGQ:信号是由一个消息放到一个空的队列上时产生的。

SI_QUEUE:信号是由sigqueue函数产生的。

SI_TIMER:信号是由使用timer_settime函数设置的某个定时器到时产生的。

SI_USER:信号是由kill函数产生的。

 

例子:该程序调用fork,子进程阻塞三种实时信号,父进程随后发送9个信号(三种实时信号中每种3个),子进程接着解阻塞信号,我们查看每种信号各有多少个递交,以及递交顺序。

代码;

 

//rtsignals/test1.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
/*
#define SIGRTMAX (sysconf(_SC_RTSIG_MAX))
#define SIGRTMIN (SYSCONF(_SC_RTSIG_MIN))
*/
static void sig_rt(int, siginfo_t *, void *);

typedef void sigfunc_rt(int, siginfo_t *, void *);//定义函数类型
sigfunc_rt *signal_rt(int, sigfunc_rt *, sigset_t *);

int main(int argc, char **argv)
{
    int i, j;
    pid_t pid;
    sigset_t newset;
    union sigval val;

    printf("SIGRTMIN = %d, SIGRTMIN = %d\n", (int) SIGRTMAX, (int) SIGRTMIN);

    if ((pid = fork()) == 0) {
        sigemptyset(&newset);
        sigaddset(&newset, SIGRTMAX);
        sigaddset(&newset, SIGRTMIN - 1);
        sigaddset(&newset, SIGRTMIN - 2);
        sigprocmask(SIG_BLOCK, &newset, NULL);

        signal_rt(SIGRTMAX, sig_rt, &newset);
        signal_rt(SIGRTMAX - 1, sig_rt, &newset);
        signal_rt(SIGRTMAX - 2, sig_rt, &newset);

        sleep(6);

        sigprocmask(SIG_UNBLOCK, &newset, NULL);
        sleep(3);
        exit(0);
    }

    sleep(3);
    for (i = SIGRTMAX; i >= SIGRTMAX - 2; i--) {
        for (j = 0; j <= 2; j++) {
            val.sival_int = j;
            sigqueue(pid, i, val);
            printf("sent signal %d, val = %d\n", i, j);
        } 
    }
    exit(0);
}

static void sig_rt(int signo, siginfo_t *info, void *context)
{
    printf("recei ved signal #%d, code = #%d, ival = %d\n", signo, info->si_code, info->si_value.sival_int);
}


sigfunc_rt *signal_rt(int signo, sigfunc_rt *func, sigset_t *mask)
{
    struct sigaction act, oact;

    act.sa_sigaction = func;
    act.sa_mask = *mask;
    act.sa_flags = SA_SIGINFO;

    if ((sigaction(signo, &act, &oact)) < 0) 
        return((sigfunc_rt *) SIG_ERR);
    return(oact.sa_sigaction);
}

 

 

 

 

 

 

转载于:https://my.oschina.net/u/178323/blog/32356

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值