常见信号介绍
SIGINT | 2 | Ctrl+C时OS送给前台进程组中每个进程 |
---|---|---|
SIGABRT | 6 | 调用abort函数,进程异常终止 |
SIGPOLL SIGIO | 8 | 指示一个异步IO事件,在高级IO中提及 |
SIGKILL | 9 | 杀死进程的终极办法 |
SIGSEGV | 11 | 无效存储访问时OS发出该信号 |
SIGPIPE | 13 | 涉及管道和socket |
SIGALARM | 14 | 涉及alarm函数的实现 |
SIGTERM | 15 | kill命令发送的OS默认终止信号 |
SIGCHLD | 17 | 子进程终止或停止时OS向其父进程发此信号 |
SIGUSR1 SIGUSR2 | 10 12 | 用户自定义信号,作用和意义由应用自己定义 |
函数API
void func(int sig)
{
printf("func for signal: %d.\n", sig);
}
signal(SIGINT, 这里是处理函数func);
因为用的参数是SIGINT,所以当我们ctrl + c时不会终止程序
signal的处理函数有三种
位置在/usr/include/i386-linux-gnu/bits/signum.h
中
可以自己写处理函数,也可以通过上面的宏来决定信号怎么处理
默认处理 | SIG_DFL |
---|---|
忽略处理 | SIG_IGN |
捕获处理 | SIG_ERR |
signal(SIGINT, 宏);
sigaction函数介绍
sigaction比signal好的一点:
sigaction可以一次得到设置新捕获函数和获取旧的捕获函数
其实还可以单独设置新的捕获或者单独只获取旧的捕获函数
而signal函数不能单独获取旧的捕获函数而必须在设置新的捕获函数的同时才获取旧的捕获函数
alarm和pause函数
alarm是内核以API形式提供的闹钟
void func(int sig)
{
if (sig == SIGALRM)
{
printf("alarm happened.\n");
}
}
signal(SIGALRM, func);
ret = alarm(5);
使用sigaction函数结合alarm
void func(int sig)
{
if (sig == SIGALRM)
{
printf("alarm happened.\n");
}
}
struct sigaction act = {
0};
act.sa_handler = func;
sigaction(SIGALRM, &act, NULL);
ret = alarm(5);
注意:alarm的返回值等于定时的时间-过去的时间
所以当返回值不是零,再调用一次alarm后,上次的alarm会被取消
pause函数—内核挂起
pause函数的作用就是让当前进程暂停运行,交出CPU给其他进程去执行。
当前进程进入pause状态后当前进程会表现为“卡住、阻塞住”,要退出pause状态当前进程需要被信号唤醒。 |
---|
使用alarm和pause结合signal来模拟sleep
alarm函数能定义时间,但不能睡眠 |
---|
pause函数能够睡眠,但是不能定义时间 |
结合一下
#include <stdio.h>
#include <unistd.h> // unix standand
#include <signal.h>
void func(int sig)
{
printf("cx_sleep: %d.\n", sig);
}
void cx_sleep(int second);
int main(int argc, char **argv)
{
cx_sleep(1);
printf("1 cx_sleep after.\n");
cx_sleep(2);
printf("2 cx_sleep after.\n");
cx_sleep(3);
printf("3 cx_sleep after.\n");
return 0;
}
void cx_sleep(int second)
{
int ret=-1;
signal(SIGALRM, func);
ret=alarm(second);
pause();
}
或是使用alarm和pause结合sigaction来模拟sleep
void func(int sig)
{
printf("cx_sleep: %d.\n", sig);
}
void mysleep(unsigned int seconds);
int main(void)
{
cx_sleep(1);
printf("1 cx_sleep after.\n");
cx_sleep(2);
printf("2 cx_sleep after.\n");
cx_sleep(3);
printf("3 cx_sleep after.\n");
return 0;
}
void mysleep(unsigned int seconds)
{
struct sigaction act = {
0};
act.sa_handler = func;
sigaction(SIGALRM, &act, NULL);
alarm(seconds);
pause();
}
```执行效果相同