Linux信号高级应用

来源:互联网 发布:池州学院网络教学平台 编辑:程序博客网 时间:2024/06/07 00:39

目录(?)[+]

Sigaction

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. SYNOPSIS  
  2.        #include <signal.h>  
  3.        int sigaction(int signum, const struct sigaction *act,  
  4.                      struct sigaction *oldact);  


功能:

     sigaction函数用于改变进程接收到特定信号后的行为。

参数

      第一个参数为信号的值,可以为除SIGKILL及SIGSTOP外的任何一个特定有效的信号(为这两个信号定义自己的处理函数,将导致信号安装错误)

      第二个参数是指向结构sigaction的指针,在结构 sigaction的实例中,指定了对特定信号的处理,可以为空,进程会以缺省方式对信号处理

      第三个参数oldact指向的对象用来保存原来对相应信号的处理,可指定oldact为NULL。

返回值

    函数成功返回0,失败返回-1

 

 

sigaction结构体

      第二个参数最为重要,其中包含了对指定信号的处理、信号所传递的信息、信号处理函数执行过程中应屏蔽掉哪些函数等等

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. /* 
  2. struct sigaction { 
  3.   //信号处理程序 不接受额外数据(比较过时) 
  4.     void (*sa_handler)(int); 
  5.  
  6.   //信号处理程序能接受额外数据,和sigqueue配合使用(支持信号排队,信号传送其他信息),推荐使用 
  7.     void (*sa_sigaction)(int, siginfo_t *, void *);          
  8.    
  9.   sigset_t sa_mask;     //屏蔽 
  10.     int sa_flags;       //表示信号的行为:SA_SIGINFO表示能接受数据 
  11.     void (*sa_restorer)(void); //废弃不用了 
  12. }; 
  13. */  

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. //示例  
  2. #define ERR_EXIT(m) \  
  3.             {\  
  4.               perror(m);\  
  5.               exit(EXIT_FAILURE);\  
  6.             }  
  7.   
  8. void onSignalAction(int signalNumber)  
  9. {  
  10.     switch(signalNumber)  
  11.     {  
  12.     case SIGINT:  
  13.         cout << "SIGINT = " << signalNumber << endl;  
  14.         break;  
  15.     case SIGQUIT:  
  16.         cout << "SIGQUIT = " << signalNumber << endl;  
  17.         break;  
  18.     default:  
  19.         cout << "Other Signal ..." << endl;  
  20.         break;  
  21.     }  
  22. }  
  23.   
  24. void onSa_SignalAction(int signalNum, siginfo_t *signalInfo, void *p)  
  25. {  
  26.     cout << "signalNum = " << signalNum << endl;  
  27. }  
  28.   
  29. int main()  
  30. {  
  31.   struct sigaction act;  
  32.   //注意:回调函数句柄sa_handler、sa_sigaction只能选其一!!!  
  33.     //act.sa_handler = onSignalAction;  
  34.     act.sa_sigaction = onSa_SignalAction;  
  35.     if (sigaction(SIGINT,&act,NULL) == -1)  
  36.         ERR_EXIT("sigaction error");  
  37.   
  38.     while (true)  
  39.     {  
  40.         pause();  
  41.     }  
  42.   
  43.     return 0;  
  44. }  

siginfo_t结构:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1.        The siginfo_t parameter to sa_sigaction is a struct with the following elements  
  2.   
  3. /* 
  4. siginfo_t{ 
  5.     int      si_signo;    /* Signal number */  
  6.     int      si_errno;    /* An errno value */  
  7.     int      si_code;     /* Signal code */  
  8.     int      si_trapno;   /* Trap number that caused 
  9.                                         hardware-generated signal 
  10.                                         (unused on most architectures) */  
  11.     pid_t    si_pid;      /* Sending process ID */  
  12.     uid_t    si_uid;      /* Real user ID of sending process */  
  13.     int      si_status;   /* Exit value or signal */  
  14.     clock_t  si_utime;    /* User time consumed */  
  15.     clock_t  si_stime;    /* System time consumed */  
  16.     sigval_t si_value;    /* Signal value */  
  17.     int      si_int;      /* POSIX.1b signal */  
  18.     void    *si_ptr;      /* POSIX.1b signal */  
  19.     int      si_overrun;  /* Timer overrun count; POSIX.1b timers */  
  20.     int      si_timerid;  /* Timer ID; POSIX.1b timers */  
  21.     void    *si_addr;     /* Memory location which caused fault */  
  22.     long     si_band;     /* Band event (was int in 
  23.                                         glibc 2.3.2 and earlier) */  
  24.     int      si_fd;       /* File descriptor */  
  25.     short    si_addr_lsb; /* Least significant bit of address 
  26.                                         (since Linux 2.6.32) */  
  27. }  
  28. */  

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. //示例:自己写signal函数  
  2. __sighandler_t mySignal(int sig, __sighandler_t handler)  
  3. {  
  4.     struct sigaction act;  
  5.     struct sigaction oldact;  
  6.     act.sa_handler = handler;  
  7.     sigemptyset(&act.sa_mask);  
  8.     act.sa_flags = 0;  
  9.   
  10.     if (sigaction(sig, &act, &oldact) < 0)  
  11.         return SIG_ERR;  
  12.   
  13.     return oldact.sa_handler;  
  14. }  

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. //示例:测试sigaction结构体第三个参数sigset_t sa_mask的作用  
  2. void handler(int sig)  
  3. {  
  4.     //信号处理函数执行的时候,阻塞sa_mask中的信号,但是SIGQUIT信号最终还会抵达  
  5.     printf("recv a sig=%d\n", sig);  
  6.     sleep(5);  
  7. }  
  8.   
  9. int main(int argc, char *argv[])  
  10. {  
  11.     struct sigaction act;  
  12.   
  13.     //设置响应函数  
  14.     act.sa_handler = handler;  
  15.     //设置屏蔽字成员  
  16.     sigemptyset(&act.sa_mask);  
  17.     sigaddset(&act.sa_mask, SIGQUIT);  
  18.     act.sa_flags = 0;  
  19.   
  20.     //注册响应信号SIGINT函数  
  21.     sigaction(SIGINT, &act, NULL);  
  22.     pause();  
  23.   
  24.     return 0;  
  25. }  

sigqueue

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. SYNOPSIS  
  2.        #include <signal.h>  
  3.        int sigqueue(pid_t pid, int sig, const union sigval value);  

功能

    sigqueue是新的发送信号系统调用,主要是针对实时信号提出的支持信号带有参数,与函数sigaction()配合使用。

    和kill函数相比多了一个参数:const union sigval value,因此sigqueue()可以比kill()传递更多的信息,但sigqueue()只能向一个进程发送信号,而不能发送信号给一个进程组。

 

 

参数

    参数1是指定接收信号的进程id,参数2确定即将发送的信号;

    参数3是一个联合数据结构union sigval,指定了信号传递的参数,即通常所说的4字节值。

 

返回值

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

 

sigval联合体

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. typedef union sigval{  
  2.     int sival_int;  
  3.     void *sival_ptr;  
  4. } sigval_t;  

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. //综合实验sigaction+sigqueue  
  2. inline void err_exit(const char *str)  
  3. {  
  4.     perror(str);  
  5.     exit(EXIT_FAILURE);  
  6. }  
  7.   
  8. void onSa_SignalAction(int signalNum, siginfo_t *signalInfo, void *p)  
  9. {  
  10.     cout << "signalNum = " << signalNum << endl;  
  11.     //int recValue = signalInfo -> si_value.sival_int;  同下  
  12.     int recValue = signalInfo -> si_int;  
  13.     cout << "recvValue = " << recValue << endl;  
  14. }  
  15.   
  16. int main()  
  17. {  
  18.     struct sigaction act;  
  19.   
  20.     sigemptyset(&act.sa_mask);  
  21.     act.sa_flags = SA_SIGINFO;  
  22.     act.sa_sigaction = onSa_SignalAction;  
  23.     if (sigaction(SIGINT,&act,NULL) == -1)  
  24.         err_exit("sigaction error");  
  25.   
  26.     pid_t pid = fork();  
  27.     if (pid == -1)  
  28.         err_exit("fork error");  
  29.     else if (pid == 0)  //In Child  
  30.     {  
  31.         /* 
  32.         typedef union sigval{ 
  33.             int sival_int; 
  34.             void *sival_ptr; 
  35.         } sigval_t; 
  36.         */  
  37.   
  38.         //union sigval signalValue; 同下  
  39.         sigval_t signalValue;  
  40.         signalValue.sival_int = 256;  
  41.         sleep(2);  
  42.   
  43.         //给父进程发送SIGINT信号  
  44.         sigqueue(getppid(),SIGINT,signalValue);  
  45.     }  
  46.   
  47.     pause();  
  48.   
  49.     return 0;  
  50. }  
0 0
原创粉丝点击