Sigaction函数
先简单说一下(sigaction、sigqueue)与(signal、kill)区别;举个例子如果有人在门外敲门,(signal、kill)只能执行敲门这个动作,而(sigaction、sigqueue)可以边敲门边对里面的人喊话(消息)。
功能:检查或修改指定信号相关联的处理动作(捕获信号出现的绑定操作)
函数原型:int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
参数说明:
signum:要捕获的信号
act:对该信号新的配置
oldact:如果不为空,那么可以对act的信号配置进行备份,方便之后进行恢复。(一般情况下赋值NULL,不备份)
返回值:成功返回 0,失败返回-1.
struct sigaction结构体介绍
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int signum, siginfo_t * info, void *////信号处理程序,能够接受额外数据和sigqueue配合使用 content);
sigset_t sa_mask;//阻塞关键字的信号集,可以再调用捕捉函数之前,把信号添加到信号阻塞字,信号捕捉函数返回之前恢复为原先的值。
int sa_flags;//影响信号的行为;SA_SIGINFO表示能够接受数据
void (*sa_restorer)(void);
};
sa_handler:与函数signal功能类似,不接收额外数据。
sa_sigaction:信号处理函数可接收额外数据。
特别说明一下,sa_sigaction 和 sa_handler 使用的是同一块内存空间,相当于 union,所以同一时间只能设置其中的一个,不能两个都同时设置。
参数*sa_sigaction(signum, siginfo_t * info, void * content);
signum:要处理的信号(要捕获/接收的信号)
info:是一个存放结构体,关于发送过来的数据是存在两个地方的,sigval_t si_value这个成员中有保存了发送过来的信息;同时,在si_int 或者si_ptr 成员中也保存了对应的数据。其中si_value结构体存放着发送数据sigval。如下图所示
content::有数据该指针非空;无数据该指针空。
union sigval {
int sival_int;
void *sival_ptr;
};
printf("Signal value:%d\n",info->si_value.sival_int);
siginfo的结构体全部信息:
siginfo_t {
int si_signo; /* Signal number */
int si_errno; /* An errno value */
int si_code; /* Signal code */
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) */
}
sigaction代码演示
include <signal.h>
#include<stdio.h>
//int sigaction(int signum, const struct sigaction *act,
// struct sigaction *oldact);
void act1(int signum,siginfo_t *info,void *content){
printf("get signum=%d\n",signum);
if(content != NULL){
printf("Sending process ID :%d\n",info->si_pid);
printf("Signal value:%d\n",info->si_value.sival_int);
//printf("Signal str:%s\n",(char*)info->si_value.sival_ptr);
}
}
int main(){
struct sigaction act;
printf("pid=%d\n",getpid());
act.sa_sigaction=act1;
act.sa_flags=SA_SIGINFO;//be able to get message
sigaction(SIGUSR1,&act,NULL);
printf("sigaction done\n");
while(1);
return 0;
}
Sigqueue函数介绍
原型:
int sigqueue(pid_t pid, int sig, const union sigval value);
参数说明:
1. pid 发送给哪个进程,pid就是那个进程的ID;
2. sig 需要发送的信号;
3. value 为需要发送的联合体(共同体),需要发送的数据都放在这里;发送过去的数据存放在info的结构体中。(上面有说到)
union sigval {
int sival_int;
void *sival_ptr;
};
返回值: 成功返回0 ,失败返回 -1。
例子:
#include <signal.h>
#include<stdio.h>
#include<stdlib.h>
#include <errno.h>
// int sigqueue(pid_t pid, int sig, const union sigval value);
int main(int argc,char**argv){
int pid;
int sig;
pid = atoi(argv[2]);//进程号
sig = atoi(argv[1]);//信号编号
union sigval sigval;
sigval.sival_int=100;//要发送的值
if(sigqueue(pid,sig,sigval)==-1){
printf("send failed\n");
perror("why");
exit(-1);
}
printf("send success\n");
return 0;
}
运行结果
先运行第一个例子

再运行第二个例子

本文介绍了Sigaction和Sigqueue函数的功能及用法,通过对比signal和kill,突出了Sigaction和Sigqueue的优势。详细解释了struct sigaction结构体各字段的作用,并提供了代码示例,帮助读者更好地理解信号处理机制。
396

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



