linux信号回调函数有参数,Linux信号高级应用

Sigaction

SYNOPSIS

#include

int sigaction(int signum, const struct sigaction *act,

struct sigaction *oldact);

功能:

sigaction函数用于改变进程接收到特定信号后的行为。

参数

第一个参数为信号的值,可以为除SIGKILL及SIGSTOP外的任何一个特定有效的信号(为这两个信号定义自己的处理函数,将导致信号安装错误)

第二个参数是指向结构sigaction的指针,在结构 sigaction的实例中,指定了对特定信号的处理,可以为空,进程会以缺省方式对信号处理

第三个参数oldact指向的对象用来保存原来对相应信号的处理,可指定oldact为NULL。

返回值

函数成功返回0,失败返回-1

sigaction结构体

第二个参数最为重要,其中包含了对指定信号的处理、信号所传递的信息、信号处理函数执行过程中应屏蔽掉哪些函数等等/*

struct sigaction {

//信号处理程序 不接受额外数据(比较过时)

void (*sa_handler)(int);

//信号处理程序能接受额外数据,和sigqueue配合使用(支持信号排队,信号传送其他信息),推荐使用

void (*sa_sigaction)(int, siginfo_t *, void *);

sigset_t sa_mask; //屏蔽

int sa_flags; //表示信号的行为:SA_SIGINFO表示能接受数据

void (*sa_restorer)(void); //废弃不用了

};

*/

//示例

#define ERR_EXIT(m) \

{\

perror(m);\

exit(EXIT_FAILURE);\

}

void onSignalAction(int signalNumber)

{

switch(signalNumber)

{

case SIGINT:

cout << "SIGINT = " << signalNumber << endl;

break;

case SIGQUIT:

cout << "SIGQUIT = " << signalNumber << endl;

break;

default:

cout << "Other Signal ..." << endl;

break;

}

}

void onSa_SignalAction(int signalNum, siginfo_t *signalInfo, void *p)

{

cout << "signalNum = " << signalNum << endl;

}

int main()

{

struct sigaction act;

//注意:回调函数句柄sa_handler、sa_sigaction只能选其一!!!

//act.sa_handler = onSignalAction;

act.sa_sigaction = onSa_SignalAction;

if (sigaction(SIGINT,&act,NULL) == -1)

ERR_EXIT("sigaction error");

while (true)

{

pause();

}

return 0;

}

siginfo_t结构:The siginfo_t parameter to sa_sigaction is a struct with the following elements

/*

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 Linux 2.6.32) */

}

*/

//示例:自己写signal函数

__sighandler_t mySignal(int sig, __sighandler_t handler)

{

struct sigaction act;

struct sigaction oldact;

act.sa_handler = handler;

sigemptyset(&act.sa_mask);

act.sa_flags = 0;

if (sigaction(sig, &act, &oldact) < 0)

return SIG_ERR;

return oldact.sa_handler;

}

//示例:测试sigaction结构体第三个参数sigset_t sa_mask的作用

void handler(int sig)

{

//信号处理函数执行的时候,阻塞sa_mask中的信号,但是SIGQUIT信号最终还会抵达

printf("recv a sig=%d\n", sig);

sleep(5);

}

int main(int argc, char *argv[])

{

struct sigaction act;

//设置响应函数

act.sa_handler = handler;

//设置屏蔽字成员

sigemptyset(&act.sa_mask);

sigaddset(&act.sa_mask, SIGQUIT);

act.sa_flags = 0;

//注册响应信号SIGINT函数

sigaction(SIGINT, &act, NULL);

pause();

return 0;

}

sigqueueSYNOPSIS

#include

int sigqueue(pid_t pid, int sig, const union sigval value);

功能

sigqueue是新的发送信号系统调用,主要是针对实时信号提出的支持信号带有参数,与函数sigaction()配合使用。

和kill函数相比多了一个参数:const union sigval value,因此sigqueue()可以比kill()传递更多的信息,但sigqueue()只能向一个进程发送信号,而不能发送信号给一个进程组。

参数

参数1是指定接收信号的进程id,参数2确定即将发送的信号;

参数3是一个联合数据结构union sigval,指定了信号传递的参数,即通常所说的4字节值。

返回值

成功返回0,失败返回-1

sigval联合体

typedef union sigval{

int sival_int;

void *sival_ptr;

} sigval_t;

//综合实验sigaction+sigqueue

inline void err_exit(const char *str)

{

perror(str);

exit(EXIT_FAILURE);

}

void onSa_SignalAction(int signalNum, siginfo_t *signalInfo, void *p)

{

cout << "signalNum = " << signalNum << endl;

//int recValue = signalInfo -> si_value.sival_int; 同下

int recValue = signalInfo -> si_int;

cout << "recvValue = " << recValue << endl;

}

int main()

{

struct sigaction act;

sigemptyset(&act.sa_mask);

act.sa_flags = SA_SIGINFO;

act.sa_sigaction = onSa_SignalAction;

if (sigaction(SIGINT,&act,NULL) == -1)

err_exit("sigaction error");

pid_t pid = fork();

if (pid == -1)

err_exit("fork error");

else if (pid == 0) //In Child

{

/*

typedef union sigval{

int sival_int;

void *sival_ptr;

} sigval_t;

*/

//union sigval signalValue; 同下

sigval_t signalValue;

signalValue.sival_int = 256;

sleep(2);

//给父进程发送SIGINT信号

sigqueue(getppid(),SIGINT,signalValue);

}

pause();

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值