Linux 超时功能

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7226603/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 05:55:42  来源:igfitidea点击:

Timeout Function

clinux

提问by Hit's

I want to make a code in which Name of User will be asked to input, but in a time limit of 15 seconds. If user cross the limit & failed to input a name(or any string), then code will be terminated & "Time Out" Massage will be display otherwise Name should be saved & "Thanks" massage will be display. I had try like this but it's wrong & not working. Please give me a solution for this.. Thanks.

我想制作一个代码,其中将要求输入用户名,但时间限制为 15 秒。如果用户超过限制且未能输入名称(或任何字符串),则代码将终止并显示“超时”按摩,否则应保存名称并显示“谢谢”按摩。我曾尝试过这样但它是错误的并且不起作用。请给我一个解决方案..谢谢。

#include <stdio.h>
#include <time.h>

int timeout ( int seconds )
{
    clock_t endwait;
    endwait = clock () + seconds * CLOCKS_PER_SEC ;
    while (clock() < endwait) {}

    return  1;
}

int main ()
{
    char name[20];
    printf("Enter Username: (in 15 seconds)\n");
    printf("Time start now!!!\n");

    scanf("%s",name);
    if( timeout(5) == 1 ){
        printf("Time Out\n");
        return 0;
    }

    printf("Thnaks\n");
    return 0;
}

采纳答案by Shrey

Probably this dummy program might help you:

可能这个虚拟程序可能会帮助你:

#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>

#define WAIT 3

int main ()
{
    char            name[20] = {0}; // in case of single character input
    fd_set          input_set;
    struct timeval  timeout;
    int             ready_for_reading = 0;
    int             read_bytes = 0;

    /* Empty the FD Set */
    FD_ZERO(&input_set );
    /* Listen to the input descriptor */
    FD_SET(0, &input_set);

    /* Waiting for some seconds */
    timeout.tv_sec = WAIT;    // WAIT seconds
    timeout.tv_usec = 0;    // 0 milliseconds

    /* Invitation for the user to write something */
    printf("Enter Username: (in %d seconds)\n", WAIT);
    printf("Time start now!!!\n");

    /* Listening for input stream for any activity */
    ready_for_reading = select(1, &input_set, NULL, NULL, &timeout);
    /* Here, first parameter is number of FDs in the set, 
     * second is our FD set for reading,
     * third is the FD set in which any write activity needs to updated,
     * which is not required in this case. 
     * Fourth is timeout
     */

    if (ready_for_reading == -1) {
        /* Some error has occured in input */
        printf("Unable to read your input\n");
        return -1;
    } 

    if (ready_for_reading) {
        read_bytes = read(0, name, 19);
        if(name[read_bytes-1]=='\n'){
        --read_bytes;
        name[read_bytes]='##代码##';
        }
        if(read_bytes==0){
            printf("You just hit enter\n");
        } else {
            printf("Read, %d bytes from input : %s \n", read_bytes, name);
        }
    } else {
        printf(" %d Seconds are over - no data input \n", WAIT);
    }

    return 0;
}

Update:
This is now tested code.

更新:
这是现在测试的代码。

Also, I have taken hints from man for select. This manual already contains a code snippet which is being used to read from the terminal and timeout in 5 seconds in case of no activity.

另外,我从 man 那里得到了提示select。本手册已经包含一个代码片段,用于在没有活动的情况下从终端读取并在 5 秒内超时。

Just a brief explanation in case the code is not well written enough:

如果代码写得不够好,请简要说明:

  1. We add the input stream (fd = 1) to the FD set.
  2. We initiate selectcall to listen to this FD set created for any activity.
  3. In case any activity occurs within the timeoutperiod, that is read through the readcall.
  4. In case there was no activity, timeout occurs.
  1. 我们将输入流 ( fd = 1)添加到 FD 集。
  2. 我们发起select呼叫以收听为任何活动创建的此 FD 集。
  3. 如果在此timeout期间发生任何活动,则通过read调用读取。
  4. 如果没有活动,则会发生超时。

Hope this helps.

希望这可以帮助。

回答by mouviciel

scanf()is not the best function to get an input in a limited time frame.

scanf()不是在有限的时间范围内获得输入的最佳功能。

Instead I would build a specific input function around select()(for managing timeout) and read()(for getting input) system calls.

相反,我会围绕select()(用于管理超时)和read()(用于获取输入)系统调用构建一个特定的输入函数。

回答by Didier Trosset

One thing you have to think about, is that you have a single thread of execution in your program. As such, the timeoutfunction will only be called when the scanffunction will be terminated. This is not what you want.

您必须考虑的一件事是,您的程序中只有一个执行线程。因此,timeout只有在scanf函数终止时才会调用该函数。这不是你想要的。

One way to do this task, is to use the selectfunction. It waits for a potentially limited amount of time (your timeout) for availability of input on some file descriptors (stdinfor you).

完成此任务的一种方法是使用该select功能。它等待可能有限的时间(您的超时)以获取某些文件描述符(stdin为您)的输入。