您的位置:首页 > 编程语言 > C语言/C++

setjmp 及 alarm实现带超时限制调用read

2015-05-25 11:34 477 查看
setjmp和longjmp函数--非局部跳转语句。

非局部指的是,这不是由普通C语言goto,语句在一个函数内实施的跳转,而是在栈上跳过若干调用帧,返回到当前函数调用路径上的某一个函数中。
#include <setjmp.h>
Int setjmp(jmp_buf env);   返回值:若直接调用则返回0,若从longjmp调用返回则返回非0值
void longjmp(jmp_buf env,int val);
    在希望返回到的位置调用setjmp,此位置在main函数中,因为直接调用该函数,所以其返回值为0.setjmp参数evn的类型是一个特殊的类型jmp_buf,这一数据类型是某种形式的数组,其中存放在调用longjmp时能用来恢复栈状态的所有信息。因为需要在另一个函数中引用env变量,所以规范的处理方式是将env变量定义为全局变量。

应用:

当检查到一个错误时,则以两个参数调用longjmp函数,第一个就是在调用setjmp时所用的env,第二个参数是具有非0值的val,它将成为从setjmp处返回的值。使用第二个参数的原因是对于一个setjmp可以有多个longjmp。

注: longjmp必须在setjmp调用之后,而且longjmp必须在setjmp的作用域之内。具体来说,在一个函数中使用setjmp来初始化一个全局标号,然后只要该函数未曾返回,那么在其它任何地方都可以通过longjmp调用来跳转到 setjmp的下一条语句执行。实际上setjmp函数将发生调用处的局部环境保存在了一个jmp_buf的结构当中,只要主调函数中对应的内存未曾释放
(函数返回时局部内存就失效了),那么在调用longjmp的时候就可以根据已保存的jmp_buf参数恢复到setjmp的地方执行。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h> //signal
#include <unistd.h> //alarm
#include <setjmp.h> //setjmp and longjmp

#define MAXBUFFLEN 1024

/*
*使用longjmp 及 alarm实现带超时限制调用read
*/

static void sig_alrm(int signo);//声明alarm信号处理函数

static jmp_buf env_alrm;

int main(int argc, char *argv[])
{
int n;
char buf[MAXBUFFLEN];

memset(buf, 0x00, sizeof(buf));

if(signal(SIGALRM, sig_alrm) == SIG_ERR){
printf("signal(SIGALRM) Error\n");
exit(-1);
}
//第一次调用setjmp会返回0,当longjmp被调用后,代码会跳转到setjmp处执行,setjmp将会返回longjmp设置的值。
if(setjmp(env_alrm) != 0){
printf("read timeout...\n");
exit(-2);
}

alarm(10);
printf("please intupt some char:");
fflush(stdout);
if((n == read(STDIN_FILENO, buf, MAXBUFFLEN)) < 0){
printf("read error...\n");
exit(-3);
}
alarm(0);
//buf[MAXBUFFLEN-1] = '\0';
//printf("%s\n", buf);
write(STDOUT_FILENO, buf, n);

return 0;
}

static void sig_alrm(int signo){
longjmp(env_alrm, 1);
}
[huangbin@devsrv3 ~]$ make setjmp
cc     setjmp.c   -o setjmp
[huangbin@devsrv3 ~]$ ./setjmp
please intupt some char:read timeout...
[huangbin@devsrv3 ~]$ ./setjmp
please intupt some char:hello,world!
[huangbin@devsrv3 ~]$
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言 setjmp signal alarm
相关文章推荐