发送实时信号 sigqueue
等待信号集只是一个掩码,仅表明一个信号是否发生,而不能表示其发生的次数。换言之,如果一个同一个信号在阻塞状态下产生了多次,那么会将该信号记录在等待信号集中,并在之后仅传递一次(仅当做发生了一次),这是标准信号的缺点之一
函数原形
#include <signal.h>
int sigqueue(pid_t pid, int sig, const union sigval)
函数参数
pid:指定接收信号的进程对应的pid
sig:指定要发送的信号,如果sig=0,则为检查进程是否存在
value:指定信号的伴随数据,union sigval 数据类型
返回值
成功:0
失败:-1,并设置errno
union sigval数据类型
typedef union sigval
{
int sival_int;
void *sival_ptr;
} sigval_t;
正点原子示例
发送进程
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
int main(int argc, char *argv[])
{
union sigval sig_val;
int pid;
int sig;
/* 判断传参个数 */
if (3 > argc)
exit(-1);
/* 获取用户传递的参数 */
pid = atoi(argv[1]);
sig = atoi(argv[2]);
printf("pid: %d\nsignal: %d\n", pid, sig);
/* 发送信号 */
sig_val.sival_int = 10; //伴随数据
if (-1 == sigqueue(pid, sig, sig_val)) {
perror("sigqueue error");
exit(-1);
}
puts("信号发送成功!");
exit(0);
}
接收进程使用 sigaction() 函数,也可以使用sa_handler函数,但是这个函数没有办法传递参数。
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
static void sig_handler(int sig, siginfo_t *info, void *context)
{
sigval_t sig_val = info->si_value;
printf("接收到实时信号: %d\n", sig);
printf("伴随数据为: %d\n", sig_val.sival_int);
}
int main(int argc, char *argv[])
{
struct sigaction sig = {0};
int num;
/* 判断传参个数 */
if (2 > argc)
exit(-1);
/* 获取用户传递的参数 */
num = atoi(argv[1]);
/* 为实时信号绑定处理函数 */
sig.sa_sigaction = sig_handler;
sig.sa_flags = SA_SIGINFO;
if (-1 == sigaction(num, &sig, NULL)) {
perror("sigaction error");
exit(-1);
}
/* 死循环 */
for ( ; ; )
sleep(1);
exit(0);
}