信号发送接收函数:sigqueue/sigaction

左心房为你撑大大i 提交于 2020-03-11 23:57:48

  信号是一种古老的进程间通信方式,下面的例子利用sigqueue发送信号并附带数据;sigaction函数接受信号并且处理时接受数据。

1、sigqueue: 新的信号发送函数,比kill()函数传递了更多附加信息,但它只能向一个进程发送信号,针对实时信号(支持排队不会丢失),与sigaction配合使用。
  int sigqueue(pid_t pid, int sig, const union sigval value);

  typedef union sigval
  {
    int sival_int;
    void *sival_ptr;
  }sigval_t;

其中第一个参数指接收信号的进程ID;第二个参数确定即将发送的信号;第三个参数指定了信号传递的参数(可用于进程间通信,传递附带数据)。函数成功返回0,失败返回-1。

2、sigaction函数可以用来接受信号进行信号处理

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

  struct  sigaction{
    void (*sa_handler)(int);
    sigset_t sa_mask;
    int sa_flag;//接收数据
    void (*sa_sigaction)(int,siginfo_t*,void*);
  };

  结构体sigaction中的sa_flags字段等于SA_SIGINFO时可以接受数据。而void (*sa_sigaction)(int,siginfo_t*,void*)函数指针的参数结构体如下:
  struct siginfo{
    int si_signo;
    int si_error;
    .
    .
    .
    union sigval si_value;//包含两个字段(int sival_int ;void *sival_ptr)

    int  si_int;  //同时,如果传递的是整数字段,也会传递到si_int中

    void *si_ptr; //如果是指针字段,也会传递到si_ptr中

    .

    .
  }
  这个结构体中的si_value对应的就是sigqueue发送过来的union sigval

 

  这个例子是两个进程之间信号传递数据的例子:

第一个程序是利用sigqueue向特定进程发送信号和数据的程序.这个程序接受一个进程号作为参数

 1 #include<unistd.h>
 2 #include<sys/types.h>
 3 #include<sys/stat.h>
 4 #include<fcntl.h>
 5 #include<stdlib.h>
 6 #include<stdio.h>
 7 #include<errno.h>
 8 #include<string.h>
 9 
10 #include<signal.h>
11 #define ERR_EXIT(m)\
12     do\
13     {\
14         perror(m);\
15         exit(EXIT_FAILURE);\
16     }while(0)  //宏要求一条语句
17 int main(int argc,char*argv[])
18 {
19     if(argc!=2){
20     fprintf(stderr,"Usage %s pid\n",argv[0]);
21     exit(EXIT_FAILURE);
22     }
23     pid_t pid=atoi(argv[1]);
24     union sigval v;
25     v.sival_int=100;
26     sigqueue(pid,SIGINT,v);
27     return 0;
28 }

 

       接下来的进程是对应上面程序的接受信号的程序,这个程序利用sigaction函数的中的信号处理程序处理信号和数据,先运行这个程序,然后上一个程序可以向这个进程发送信号:

 1 #include<unistd.h>
 2 #include<sys/types.h>
 3 #include<sys/stat.h>
 4 #include<fcntl.h>
 5 #include<stdlib.h>
 6 #include<stdio.h>
 7 #include<errno.h>
 8 #include<string.h>
 9 
10 #include<signal.h>
11 #define ERR_EXIT(m)\
12     do\
13     {\
14         perror(m);\
15         exit(EXIT_FAILURE);\
16     }while(0)  //宏要求一条语句
17 void handler(int sig,siginfo_t* info,void* ctx);
18 int main(int argc,char*argv[])
19 {
20     struct sigaction act;
21     act.sa_sigaction=handler;//不能使用sa_handler函数了,要使用 void (*sa_sigaction) (int,siginfo_t*,void*)
22     sigemptyset(&act.sa_mask);
23     act.sa_flags=SA_SIGINFO;//指定sa_flags传递数据
24     if(sigaction(SIGINT,&act,NULL)<0)
25         ERR_EXIT("sigaction error\n");
26     for(;;)
27         pause();
28     return 0;
29 }
30 
31 void handler(int sig,siginfo_t* info,void* ctx)
32 {    
33     printf("receive a sig=%d\n,data=%d\n",sig,info->si_value.sival_int);
34     
35 }

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!