linux c++ 限时输入

#include<unistd.h>
#include<signal.h>
#include<stdio.h>
#include<stdlib.h>
#include<setjmp.h>

#define MAXLINE 4096

static void sig_alrm(int);

static jmp_buf env_alrm;

int main(void)
{
        int n;
        char line[MAXLINE];

        if(signal(SIGALRM, sig_alrm) == SIG_ERR)
                printf("signal(SIGALRM) error!\n");
    if(setjmp(env_alrm) != 0)
    {
        printf("read timeout!\n");
        return -1;
    }
        alarm(10);
        //这里存在竞争条件
        //依赖 中断的系统调用, 如果系统自动重启系统调用,则无效
        if((n = read(STDIN_FILENO, line, MAXLINE)) < 0)
                printf("read error");
        alarm(0);

        write(STDOUT_FILENO, line, n);
        return 0;
}

static void sig_alrm(int signo)
{
        //do nothing
        longjmp(env_alrm,1);
        printf("sig_alrm!");
}



函数原型:
int setjmp(jmp_buf envbuf);
setjmp函数用缓冲区envbuf保存系统堆栈的内容,以便后续的longjmp函数使用。setjmp函数初次启用时返回0值。
 
void longjmp(jmp_buf envbuf, int val);
longjmp函数中的参数envbuf是由setjmp函数所保存的堆栈环境,参数val设置setjmp函数的返回值。longjmp函数本身是没有返回值的,它执行后跳转到保存envbuf参数的setjmp函数调用,并由setjmp函数调用返回,此时setjmp函数的返回值就是val。
 
调用longjmp函数时不能使setjmp函数返回0,如果val为0,则setjmp函数返回1。longjmp函数从来不返回,因为它调用后就跳转到setjmp函数保存的堆栈处,恢复堆栈开始执行,所以longjmp函数不会返回。


例子用到了 alarm 定时器函数。指向sig_alrm().

你可能感兴趣的:(linux c++ 限时输入)