信号接收函数
信号【入门】虽然发送和接收到了信号,但是我们可以让信号再携带一些数据,这样我们需要另外的函数在信号传递的过程中,携带一些数据。
1. 原型:
#include <signal.h>
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
[参数int signum]:信号的编号
[参数int const struct sigaction *act]:若不为空说明需要对该信号有新的配置
[参数int const struct sigaction *oldact]:若不为空,可对之前的信号配置进行备份。
struct sigaction为一个结构体,其原型为:
struct sigaction {
void (*sa_handler)(int);
//信号处理程序,不接受额外数据,SIG_IGN 为忽略,SIG_DFL 为默认动作
void (*sa_sigaction)(int, siginfo_t *, void *);
//信号处理程序,能够接受额外数据和sigqueue配合使用
sigset_t sa_mask;
//阻塞关键字的信号集,可以再调用捕捉函数之前,把信号添加到信号阻塞字,信号捕捉函数返回之前恢复为原先的值。
int sa_flags;
//影响信号的行为SA_SIGINFO表示能够接收数据
}
- 第二个参数中的void* 是接收到信号所携带的额外数据;而struct siginfo这个结构体主要适用于记录接收信号的一些相关信息,可接收的信息如下。
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 */
int si_band; /* Band event */
int si_fd; /* File descriptor */
}
- 如果第四个参数 sa_flags设置为 SA_SIGINFO 属性时,说明了信号处理程序带有附加信息,也就是会调用 sa_sigaction 这个函数指针所指向的信号处理函数。否则,系统会默认使用 sa_handler 所指向的信号处理函数。
2.接收端代码如下:
sigaction_rec.c
#include <signal.h>
#include <stdio.h>
void handler(int signum,siginfo_t *info,void *context)
{
printf("rec signum = %d\n",signum );
if(signum != 0){
printf("get data = %d\n",info->si_int);
printf("get data = %d\n",info->si_value.sival_int);
printf("send_pid = %d\n",info->si_pid);
}
}
int main()
{
printf("rec_pid = %d\n",getpid());
struct sigaction act;
act.sa_sigaction = handler;
act.sa_flags = SA_SIGINFO;
sigaction(SIGUSR1,&act,NULL);
while(1);
return 0;
}
信号发送函数
1.原型
int sigqueue(pid_t pid, int sig, const union sigval value);
[参数const pid]:进程号
[参数const sig]:信号编号
[参数const union sigval value]:为一个联合类型,可以使用 value 参数向信号处理程序传递整数值或者指针值。
union sigval {
int sival_int;
void *sival_ptr;
};
2.发送端代码
sigaction_sent.c
#include<signal.h>
#include<stdio.h>
int main(int argc, char **argv)
{
int signum;
int pid;
signum = atoi(argv[1]);
pid = atoi(argv[2]);
union sigval value;
value.sival_int = 100;
sigqueue(pid,signum,value);
printf("send_pid = %d\n",getpid());
return 0;
}
编译运行结果:
接收端:

发送端:

本文详细介绍了如何在信号处理中携带额外数据,包括使用sigaction和sigqueue函数的方法。通过实例代码展示了信号发送与接收的过程,以及如何在信号处理函数中获取发送方PID和信号携带的数据。

被折叠的 条评论
为什么被折叠?



