首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使read()非阻塞和重设read()

如何使read()非阻塞和重设read()
EN

Stack Overflow用户
提问于 2016-01-08 23:59:25
回答 1查看 322关注 0票数 1

所以我做了这个函数,它的作用就像一个倒计时,我想在倒计时减少的时候读一个命令。我的大问题是让read()等待输入,倒计时是decreasing.As,您可以看到,我尝试使用select(),但是在第一个printf("timeout.\n");之后,它停止了读取。我只做了一次timeout,否则它会一直到倒计时达到0。我要再读一遍。

代码语言:javascript
复制
int timer(int seconds) 
{
    time_t start, end;
    double elapsed;
    int opened=0; 
    char command[10];
    struct timeval tv;
    int fd_stdin,rv;
    fd_set rd;

    fd_stdin=fileno(stdin);

    FD_ZERO(&rd);
    FD_SET(fileno(stdin),&rd);

    tv.tv_sec=5;
    tv.tv_usec=0;

    time(&start);  /* start the timer */

    do
    {
        time(&end);

        elapsed = difftime(end, start);

        if(fmod(elapsed,5)==0)
        {
            printf("Time remaining: %f minutes.\n", (seconds-elapsed)/60);
            sleep(1);
            if(opened==0)
            {
                printf("Use opentest to open your test.\n");
                opened=1;
            }
            fflush(stdout);
        }
        int c;
        rv=select(fd_stdin+1,&rd,NULL,NULL,&tv);
        if(rv==-1)
        {
            perror("Error on select.\n");
            exit(1);
        }
        else if (rv==0 && c!=1)
        {
            printf("timeout.\n");
            rv=select(fd_stdin+1,&rd,NULL,NULL,&tv);
            c=1;
        }
        else 
        {
            c=0;
            read(fd_stdin,command,10);
        }
    }
    while(elapsed < seconds);
    return 0;
}

编辑:要使用fmod()函数,我编译如下:gcc client.c -lm -o client.exe。我不认为这是问题所在,但我不确定。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-09 01:53:33

select()在退出时修改fd_set,以反映已发出信号的描述符。每次超时后,您都不会重置fd_set

而且,在某些平台上,select()修改timeval结构以反映还有多少时间,因此每次在这些平台上调用select()时都必须重置timeval

另外,您的c变量在循环中声明,并且未初始化。把它移到循环之外。

尝试更像这样的东西:

代码语言:javascript
复制
int timer(int seconds) 
{
    time_t start, end;
    double elapsed;
    int opened = 0; 
    char command[10];
    struct timeval tv;
    int fd_stdin, rv;
    fd_set rd;
    int c = 0;

    fd_stdin = fileno(stdin);

    time(&start);  /* start the timer */

    do
    {
        time(&end);

        elapsed = difftime(end, start);

        if (fmod(elapsed, 5) == 0)
        {
            printf("Time remaining: %f minutes.\n", (seconds-elapsed)/60);
            sleep(1);
            if (opened == 0)
            {
                printf("Use opentest to open your test.\n");
                opened = 1;
            }
            fflush(stdout);
        }

        FD_ZERO(&rd);
        FD_SET(fd_stdin, &rd);

        tv.tv_sec = 5;
        tv.tv_usec = 0;

        rv = select(fd_stdin+1, &rd, NULL, NULL, &tv);
        if (rv == -1)
        {
            perror("Error on select.\n");
            exit(1);
        }
        else if (rv == 0)
        {
            if (c != 1)
            {
                printf("timeout.\n");
                c = 1;
            }
        }
        else 
        {
            c = 0;
            read(fd_stdin, command, 10);
        }
    }
    while (elapsed < seconds);
    return 0;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34688073

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档