linux系统中的实时信号

您所在的位置:网站首页 linux实时打印程序信息内容是什么 linux系统中的实时信号

linux系统中的实时信号

2024-07-17 06:42| 来源: 网络整理| 查看: 265

标准信号的局限性:

1. 阻塞信号可能会丢失。当一个信号阻塞时,这个信号即使多次发送给进程,也被执行一次信号句柄。

2. 信号交付没有携带与信号有关信息。接受到信号的进程无法区分同种信号的不同情况,也不知道信号从何而来。

3. 信号的交付没有优先级。当有多个信号悬挂与一个进程时,交付的顺序不确定。

实时信号对标准信号做了一下扩充,有以下的特点:

1.增加了信号从SIGRTMIN到SIGRTMAX的实时信号,可以通过sysconf(_SC_RTSIG_MAX)获得当前操作系统支持的实时信号的个数。

2. 实时信号在队列中并按顺序交付。同一类型的实时信号将按顺序交付给进程。

3. 实时信号可以携带额外的信息。

4. 进程能够通过专门的函数更快的回复信号。

5. 当定时器到期、空消息队列有消息到达、有异步IO完成时,信号能够及时交付给进程。

通过设置sigaction结构体中的sa_flags标志为SA_SIGNFO实现实时信号句柄的安装。此时的信号句柄原型为void func(int signo,siginfo_t *info,void *context);

typedef struct { int si_signo; int si_code; union sigval si_value; pid_t pid; uid_t si_uid; void *si_addr; int sj_status; long si_band; } siginfo_t;

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

使用sigqueue发送实时信号可以在进程中排队,进程优先相应信号值(value)大的信号,对于相同的信号值按照发送的顺序执行。对于标准信号优先响应且不能排队。

void sigwaitinfo(const sigset_t *set, siginfo_t *info); void sigtimedwait(const sigset_t *set,siginfo_t *info,const struct timespec *timeout); sigwaitinfo()等待set信号集合中的中的信号到来,如果要等待的信号没有出现则无限期被挂起。

sigtimedwait()等待set信号的集合中的信号到来,若没有等待信号集中信号到来则悬挂进程直到timeout的时间的到来。

实时信号句柄设置和发送的具体实例:

/* * main.c * * Created on: 2016年10月19日 * Author: chy */ #include #include #include #include #include #include #include #define ERR(msg) { \ fprintf(stderr,"%s\n",msg); \ exit(-1); \ } void print(int sig,siginfo_t *info,void *exits) { printf("signal is %d,valur is %d ppid is %d\n",sig,info->si_value.sival_int,info->si_pid); if(!info->si_value.sival_int) exit(0); } int main(int argc,char *argv[]) { pid_t pid; sigset_t set,old_set; if((pid = fork()) == 0){ struct sigaction action; if(sigaction(SIGINT,&action,NULL)) ERR("get aignal fail"); sigemptyset(&set); sigaddset(&set,SIGRTMIN); sigaddset(&set,SIGRTMIN + 1); sigaddset(&set,SIGINT); sigprocmask(SIG_BLOCK,&set,&old_set); action.sa_mask = set; action.sa_flags = SA_SIGINFO; action.sa_sigaction = print; if(sigaction(SIGRTMIN,&action,NULL) || sigaction(SIGRTMIN + 1,&action,NULL) || sigaction(SIGINT,&action,NULL)) ERR("sigaction add fial"); while(1) sigsuspend(&old_set); //用旧的信号代替已屏蔽的新的信号集 } else { union sigval val; int sta; sleep(2); val.sival_int = 1; sigqueue(pid,SIGRTMIN + 1,val); val.sival_int = 2; sigqueue(pid,SIGRTMIN,val); val.sival_int = 5; sigqueue(pid,SIGRTMIN,val); val.sival_int = 3; sigqueue(pid,SIGINT,val); val.sival_int = 4; sigqueue(pid,SIGINT,val); val.sival_int = 4; sigqueue(pid,SIGRTMIN,val); wait(&sta); //printf("child exit %d",WEXITSATUS(stat)); exit(0); } }

sigtimedwait等待函数的具体事例:

#include #include #include #include #include #define err(msg) { \ fprintf(stderr,"%s\n",msg); \ exit(1); \ } int main(int argc,char *argv[]) { int sig_max,i; sigset_t set; sig_max = sysconf(_SC_RTSIG_MAX); //获取系统支持的最大实时信号数 sigfillset(&sig_max); sigprocmask(SIG_SETMASK,&set,NULL); //阻塞所有信号 if(fork() == 0){ //创建子进程 printf("this is child\n"); union sigval gval; //信号量数 for(i = 0; i < sig_max - 1; i++){ gval.sival_int = i; if(sigqueue(getppid(), SIGRTMIN + i, gval)) //发送信号给父进程 err("bulid is fail"); } exit(0); } printf("this is parent\n"); siginfo_t info; struct timespec time_out; //设置等待时间 time_out.tv_sec = 0; time_out.tv_nsec = 2; while(1){ if(sigtimedwait(&set,&info,&time_out) < 0 && errno == EAGAIN){ //等待信号的到来 printf("this time out\n"); exit(0); } if(info.si_code != SI_QUEUE) //判断是否为实时信号 printf("this is %d but it is not send sigqueu\n",info.si_signo); else printf("signo=%d pid=%d val=%d\n",info.si_signo,info.si_pid,info.si_value.sival_int); } }



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3