signal.h
库变量
sig_atomic_t | 是 int 类型,在信号处理程序中作为变量使用。它是一个对象的整数类型,该对象可以作为一个原子实体访问,即使存在异步信号时,该对象可以作为一个原子实体访问。 |
库宏
SIG_DFL | 默认的信号处理程序。 |
SIG_ERR | 表示一个信号错误。 |
SIG_IGN | 忽视信号。 |
SIG
宏用于表示以下各种条件的信号码:
SIGABRT | 程序异常终止。 |
SIGFPE | 算术运算出错,如除数为 0 或溢出。 |
SIGILL | 非法函数映象,如非法指令。 |
SIGINT | 中断信号,如 ctrl-C。 |
SIGSEGV | 非法访问存储器,如访问不存在的内存单元。 |
SIGTERM | 发送给本程序的终止请求信号。 |
库函数
void (*signal(int sig, void (*func)(int)))(int) | 该函数设置一个函数来处理信号,即信号处理程序。 |
int raise(int sig) | 该函数会促使生成信号 sig。sig 参数与 SIG 宏兼容。 |
void sighandler(int);
int main()
{
signal(SIGINT, sighandler);
printf("generate a signal\n");
raise(SIGINT);
printf("exit\n");
return(0);
}
void sighandler(int)
{
printf("get a signal\n");
}
setjmp.h
setjmp
和longjmp
函数提供了一种类似沟通语句的机制,但它不局限于一个函数的作用域之内,这些函数常用于深层嵌套的函数调用链。如果在某低层的函数中检测到一个错误,可以立即返回到顶层函数,不必向调用链中每个中间层函数返回一个错误标志。
声明一个jmp_buf
变量,并调用setjmp
函数对其初始化,setjmp
函数返回0,setjmp
会把程序的状态信息(例如,堆栈指针的当前位置和程序的计数器)保存到跳转缓冲区,调用setjmp
时所处的函数就会成为顶层函数。以后,在顶层函数或其他任何他所调用的函数(直接调用或者间接调用)中调用longjmp
函数,将导致这个被保存的状态重新恢复。longjmp
的作用就使执行流通过再次从setjmp
函数返回,从而立即跳回到顶层函数中。
setjmp
函数第一次被调用时,它返回0。当setjmp
作为longjmp
的执行结果再次返回时,他的返回值是longjmp
的第二个参数,它必须是个非0值。通过检查他的返回值,程序可以判断是否调用了longjmp
,如果存在多个longjmp
也可以判断出哪个longjmp
被调用。
库变量
jmp_buf | 一个用于存储宏 setjmp() 和函数 longjmp() 相关信息的数组类型。 |
库宏
int setjmp(jmp_buf environment) | 这个宏把当前环境保存在变量 environment 中,以便函数 longjmp() 后续使用。如果这个宏直接从宏调用中返回,则它会返回零,但是如果它从 longjmp() 函数调用中返回,则它会返回一个非零值。 |
库函数
void longjmp(jmp_buf environment, int value) | 该函数恢复最近一次调用 setjmp() 宏时保存的环境,jmp_buf 参数的设置是由之前调用 setjmp() 生成的。 |
#include <stdio.h>
#include <setjmp.h>
static jmp_buf buf;
void second(void) {
printf("second\n"); // 打印
longjmp(buf,1); // 跳回setjmp的调用处 - 使得setjmp返回值为1
}
void first(void) {
second();
printf("first\n"); // 不可能执行到此行
}
int main() {
if ( ! setjmp(buf) ) {
first(); // 进入此行前,setjmp返回0
} else { // 当longjmp跳转回,setjmp返回1,因此进入此行
printf("main\n"); // 打印
}
return 0;
}