信号是一种古老的进程间通信方式,下面的例子利用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 }
来源:https://www.cnblogs.com/wsw-seu/p/8379028.html