Linux—信号如何携带消息之高级版
携带消息原理:
1、 绑定 sigaction()
2、sigqueue() 发送消息
1、接受、绑定信号sigaction()原函数
#include <signal.h>
//绑定信号
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
参数:
signum: 要捕捉的信号
act : 结构体 (要配置的三个重要参数)
oldact: NULL(堵塞)
act结构需要配置的参数:
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
参数:
1、s1a_handler:(不配置)信号处理函数,不接受额外数据,SIG_IGN 为忽略,SIG_DFL 为默认。
2、sa_sigaction:定义信号处理函数,能够接受额外数据
a、int :捕捉到相应的信号值
b、siginfo_t * :si_value保存了发送过来的信息,同时,在 si_int或者 si_ptr成员中也保存了对应的数据
c、void * :信号携带消息的有效值(判断是否为NLL)
3、sa_mask :不配置(默认阻塞关键字的信号)
4、sa_flags :SA_SIGINFO 宏接受数据
siginfo_t结构体:
获取信号的信息
siginfo_t {
int si_signo; /* Signal number */
int si_errno; /* An errno value */
int si_code; /* Signal code */
int si_trapno; /* Trap number that caused
hardware-generated signal
(unused on most architectures) */
pid_t si_pid; /* Sending process ID */
uid_t si_uid; /* Real user ID of sending process */
int si_status; /* Exit value or signal */
clock_t si_utime; /* User time consumed */
clock_t si_stime; /* System time consumed */
sigval_t si_value; /* Signal value */
int si_int; /* POSIX.1b signal */
void *si_ptr; /* POSIX.1b signal */
int si_overrun; /* Timer overrun count; POSIX.1b timers */
int si_timerid; /* Timer ID; POSIX.1b timers */
void *si_addr; /* Memory location which caused fault */
long si_band; /* Band event (was int in
glibc 2.3.2 and earlier) */
int si_fd; /* File descriptor */
short si_addr_lsb; /* Least significant bit of address
(since kernel 2.6.32) */
}
接收端demo:
#include <signal.h>
#include <stdio.h>
//void (*sa_sigaction)(int, siginfo_t *, void *);
void handler(int signum, siginfo_t *data , void * text)
{
printf("get signal:%d\n",signum);
if(text != NULL ){
printf("from_pid:%d\n",data->si_pid);
printf("data1:%d\n",data->si_int);
printf("data2:%d\n",data->si_value.sival_int);
}
}
int main()
{//int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
struct sigaction act;//定义参数2结构体
printf("pid=%d\n",getpid());
act.sa_sigaction =handler;//处理消息函数
act.sa_flags = SA_SIGINFO;//SA_SIGINFO 宏接受数据
sigaction(SIGUSR1,&act,NULL);
while(1);
system("pause");
return 0;
}
2、sigqueue() 发送消息
sigqueue()函数原型:
int sigqueue(pid_t pid, int sig, const union sigval value); 发消息
参数:
pid :进程pid号
sig :捕捉的信号
value联合体 :发的内容
union sigval {
int sival_int;
void *sival_ptr;
};
发送端demo:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char **argv)
{
int pid;
int signum;
// int sigqueue(pid_t pid, int sig, const union sigval value);
printf("pid=%d\n",getpid());
pid = atoi(argv[2]); //字符转为整形
signum = atoi(argv[1]);
union sigval value;
value.sival_int = 200;
sigqueue(pid, signum,value);
system("pause");
return 0;
}
运行结果: