linux应用基础知识点11-IPC之信号
信号
信号是内容受限的一种异步通信机制,本质是一个预定义的数字编号。
内容受限——只能传递信号值,不能传递更详细的内容。
异步——事先并不知道信号何时发生,类似于中断都是突然发生的。
发出者:
1.终端按键
2.硬件异常内核发出信号
3.用户发出kill命令
4.某些软件条件满足后发出信号,如alarm时钟到时间产生SIGALARM信号,向写端已关闭的管道write时会产生SIGPIPE信号。
常见信号:
SIGINT 2 Ctrl+C时OS送给前台进程组中每个进程(注意“前台”、“每个”)
SIGPOLL(SIGIO) 6 指示一个异步IO事件
SIGKILL 9 杀死一个进程的信号
SIGPIPE 13 涉及管道和socket
SIGALARM 14 涉及alarm函数
SIGTERM 15 kill命令发送的默认信号
SIGCHLD 17 子进程终止或停止时,OS发送给父进程的信号
SIGUSR1/SIGUSR2 10/12 用户自定义信号
signal函数
sighandler_t signal(int signum, sighandler_t handler);
用于设置某个信号的处理方式,常用的有下面三种(以SIGINT为例):
signal(SIGINT, SIG_IGN); //设置SIGINT信号的处理方式为忽略方式
signal(SIGINT, SIG_DFL); //设置为默认处理方式
signal(SIGINT, func_xxx); //用户定义的处理函数func_xxx
当signal执行成功时,返回老的处理函数;当执行失败时,返回SIG_ERR。
sigaction函数
由于继承自unix系统的signal函数存在移植性不好的问题,这里提供了符合posix标准的sigaction函数来替代。
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
1.act和oldact都不为NULL时,该函数设置新处理函数act,同时获取旧处理函数oldact;
2.act为NULL时,可以只获取而不改变当前处理函数;
3.oldact为NULL时,可以直接设置新处理函数,不获取旧处理函数。
alarm函数
unsigned int alarm(unsigned int seconds);
该函数可以实现指定时段到了以后,向此函数的进程发出SIGALRM信号。
如果参数seconds设为0,则关闭之前设置的闹钟;
如果之前没设置过闹钟,则返回一个0;
如果之前设置过闹钟,则返回之前闹钟剩余的时间。
pause函数
int pause(void);
该函数将进程设为暂停态,可以用信号唤醒。
综合应用:
实现一个类似于sleep的函数。
void alarm_func(int sig) //闹钟信号处理函数
{
if(sig == SIGALRM) {}
}
void mysleep(unsigned int seconds) //自定义睡眠函数
{
struct sigaction act = {0};
act.sa_handler = alarm_func;
sigaction(SIGALRM, &act, NULL); //设置闹钟信号的处理函数
alarm(seconds); //设置闹钟
pause(); //暂停进程
}