目录
1、signal
signal()函数声明如下:
/* Type of a signal handler. */
typedef void (*__sighandler_t) (int);
/* Set the handler for the signal SIG to HANDLER, returning the old
handler, or SIG_ERR on error.
By default `signal' has the BSD semantic. */
__BEGIN_NAMESPACE_STD
#ifdef __USE_MISC
extern __sighandler_t signal (int __sig, __sighandler_t __handler)
__THROW;
#else
__sighandler_t是一个函数指针 ,signal函数的功能就是为信号__sig注册处理函数,函数的指针为__handler。
/*================================================================
* Copyright (C) 2021 baichao All rights reserved.
*
* 文件名称:Signal.cpp
* 创 建 者:baichao
* 创建日期:2021年02月10日
* 描 述:
*
================================================================*/
#include <iostream>
#include <signal.h>
#include <unistd.h>
void do_handler(int _signal)
{
if(_signal == SIGIO)
std::cout<<"SIGIO"<<std::endl;
else if(_signal == SIGUSR1)
std::cout<<"SIGUSR1"<<std::endl;
else if(_signal == SIGUSR2)
std::cout<<"SIGUSR2"<<std::endl;
else
std::cout<<"啥也不是"<<std::endl;
}
int main()
{
signal(SIGIO,do_handler);
signal(SIGUSR2,do_handler);
signal(SIGUSR1,do_handler);
std::cout<<SIGIO<<std::endl;
std::cout<<SIGUSR1<<std::endl;
std::cout<<SIGUSR2<<std::endl;
while(1)
sleep(1);
return 0;
}
通过kill发送信号到对应进程。
2、sigaction
siginfo_t结构体定义如下:
/*/usr/include/x86_64-linux-gnu/bits/siginfo.h*/
typedef struct
{
int si_signo; /* Signal number. */
int si_errno; /* If non-zero, an errno value associated with
this signal, as defined in <errno.h>. */
int si_code; /* Signal code. */
union
{
int _pad[__SI_PAD_SIZE];
/* kill(). */
struct
{
__pid_t si_pid; /* Sending process ID. */
__uid_t si_uid; /* Real user ID of sending process. */
} _kill;
/* POSIX.1b timers. */
struct
{
int si_tid; /* Timer ID. */
int si_overrun; /* Overrun count. */
sigval_t si_sigval; /* Signal value. */
} _timer;
/* POSIX.1b signals. */
struct
{
__pid_t si_pid; /* Sending process ID. */
__uid_t si_uid; /* Real user ID of sending process. */
sigval_t si_sigval; /* Signal value. */
} _rt;
/* SIGCHLD. */
struct
{
__pid_t si_pid; /* Which child. */
__uid_t si_uid; /* Real user ID of sending process. */
int si_status; /* Exit value or signal. */
__sigchld_clock_t si_utime;
__sigchld_clock_t si_stime;
} _sigchld;
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
struct
{
void *si_addr; /* Faulting insn/memory ref. */
short int si_addr_lsb; /* Valid LSB of the reported address. */
struct
{
void *_lower;
void *_upper;
} si_addr_bnd;
} _sigfault;
/* SIGPOLL. */
struct
{
long int si_band; /* Band event for SIGPOLL. */
int si_fd;
} _sigpoll;
/* SIGSYS. */
struct
{
void *_call_addr; /* Calling user insn. */
int _syscall; /* Triggering system call number. */
unsigned int _arch; /* AUDIT_ARCH_* of syscall. */
} _sigsys;
} _sifields;
} siginfo_t __SI_ALIGNMENT;
sigaction声明如下:
/*/usr/include/x86_64-linux-gnu/bits/sigaction.h*/
/* Structure describing the action to be taken when a signal arrives. */
struct sigaction
{
/* Signal handler. */
#ifdef __USE_POSIX199309
union
{
/* Used if SA_SIGINFO is not set. */
__sighandler_t sa_handler;
/* Used if SA_SIGINFO is set. */
void (*sa_sigaction) (int, siginfo_t *, void *);
}
__sigaction_handler;
# define sa_handler __sigaction_handler.sa_handler
# define sa_sigaction __sigaction_handler.sa_sigaction
#else
__sighandler_t sa_handler;
#endif
/* Additional set of signals to be blocked。就是当处理当前__sig信号时暂时将sa_mask指定的一组信号阻塞 */
__sigset_t sa_mask;
/* Special flags.
sa_flags用来设置信号处理的其他相关操作,下列的数值可用:
A_NOCLDSTOP:如果参数signum为SIGHLD,则当前子进程暂停时并不会通知父进程
SA_ONESHOT/SA_RESETHAND:当调用新的信号处理函数前,将此信号处理方式改为系统预设的方式
SA_RESTART:被信号中断的系统调用会自行重启
SA_NOMASK/SA_NODEFER:在处理此信号未结束前不理会此信号的再次到来,如果参数oldact不是NULL指针,则原来的信号处理方式会由此结构sigaction返回。
*/
int sa_flags;
/* Restore handler. */
void (*sa_restorer) (void);
};
/*/usr/include/signal.h*/
/* Get and/or set the action for signal SIG. success return 1,else 0. */
/*__sig参数指出要捕获的信号类型,__restrict __act参数指定新的信号处理方式,__restrict __oact参数输出先前信号的处理方式(如果不为NULL的话)*/
extern int sigaction (int __sig, const struct sigaction *__restrict __act,
struct sigaction *__restrict __oact) __THROW;
如果需要携带信息(即siginfo_t的指针有值)则使用sa_sigaction,否则使用sa_handler。
示例代码:
/*================================================================
* Copyright (C) 2021 baichao All rights reserved.
*
* 文件名称:Sigaction.cpp
* 创 建 者:baichao
* 创建日期:2021年02月15日
* 描 述:
*
================================================================*/
#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <cstring>
void do_handler(int _signal, siginfo_t *act,void *context)
{
std::cout<<"信号编号为:"<<_signal<<std::endl;
std::cout<<"sigaction.si_signo:"<<act->si_signo<<std::endl;
std::cout<<"sigaction.si_code:"<<act->si_code<<std::endl;
std::cout<<*(std::string*)context<<std::endl;
}
int main()
{
struct sigaction act,oldact;
act.sa_sigaction = do_handler;
act.sa_flags = SA_ONESHOT|SA_NOMASK;
sigaction(SIGUSR1,&act,&oldact);
while(1)
sleep(1);
}