用C ++输入超时

Boe*_*Noe 5 c++ windows winapi timing

我想要一个程序,让用户有10秒钟的时间输入密码。如果计时器超过10秒,程序将显示一条消息。我当前的代码是这样的:

 #include <iostream>
 #include <ctime>
 #include <string>

int main(){
std::string password;

int start_s=clock();

int stop_s=clock();
if(stop_s-start_s <= 0){

    std::cout << "TIME RAN OUT!";
}
std::cout << "Enter your password! \n";
std::cout << "Password: ";
std::cin >> password;
std::cout << "\n \n";

if (password == "password123"){

    std::cout << "Correct!";
} else {
    std::cout << "Wrong!";
}

}
Run Code Online (Sandbox Code Playgroud)

这当然是行不通的...但是我不确定下一步该怎么做...有什么想法吗?

如果您需要更多详细信息,请在评论中提问。

编辑:

我刚刚意识到问题出在哪里……花了一个时间戳,然后迅速制作了另一个时间戳。当发现差异时,它低于0 ...

但是我仍然不知道下一步该怎么做...

use*_*500 5

您试图做的是读取stdin具有10秒超时时间的非阻塞(异步)消息。这不太难,但是根据您当前的水平,可能涉及许多新概念。

这里的关键概念是,cin >> password;阻塞调用,也就是说,直到它完成,控制不会进一步验证码流。因此,我们需要以某种方式使它成为非阻塞状态,或者使其保持阻塞状态并在超时到期时中断它。

根据系统的设计要求和约束,有一些常见的实现。每种实现因操作系统而异,但技术非常相似。

1.异步:带超时的STDIN 此方法通常在网络编程中使用,并且可以扩展到其他形式的输入,例如当前情况。

  1. 将标准输入(STDIN)句柄(句柄= 0)放入“监视列表”。
  2. 将超时放置在监视列表上。
  3. 只要STDIN发生更改,就进行处理。
  4. 超时到期后,请检查我们处理的内容是否能完成工作。

在Linux(以及许多其他Unix风格)中,可以使用FD_SETselect系统调用来处理监视列表。在Windows中,您需要使用WaitForMultipleEvents

我不确定出于这个问题的目的,我是否可以公正地准确解释这些概念。作为参考,其中有一些代码指针完全一样的东西另一个问题是在这里

2.同步:带中断的多线程 这是用于需要精细事件调度程序/计时器的情况的常用技术。

  1. 创建两个线程,A然后B
  2. A 将等待指示的超时。
  3. B 将等待阻塞读取
  4. 如果AB完成之前终止(超时),则A发出信号BB决定下一步要做什么(终止,重复消息等)
  5. 如果B读取密码没问题,则B发出信号A并要求其死掉。

实现此目的的另一种方法是使OS中断线程B注释之一所述。

3.同步:轮询 这用于以下情况随着时间的推移,我们不需要太多的细粒度控制。

  1. 使用非阻塞读取(kbhit())检查输入中是否有任何内容
  2. 如果没有,并且超时中还有剩余时间,请等待更短的时间delta(例如10ms
  3. 如果超时已到期,并且没有剩余时间,请执行所需的任何处理(向用户发送消息,退出等)

请注意,在这种情况下,取决于delta,该方法可能会消耗大量CPU,并且效率可能很低。例如,如果delta=10ms如上所述,该线程将每秒被唤醒100次,并且效率不高,尤其是当用户没有在键盘上以如此快的速度键入字符时。