c++ - 在 C++ 中输入超时

标签 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!";
}

}

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

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

编辑:

我才意识到问题出在哪里... 花了一个时间戳,然后很快又做了一个时间戳。当发现差异时,它低于 0...

但是我还是不知道接下来要做什么...

最佳答案

您正在尝试做的是从 stdin 中以 10 秒的超时时间进行非阻塞(异步)读取。这不是太难,但可能涉及许多新概念,具体取决于您当前的水平。

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

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

<强>1。异步:带超时的 STDIN 这种方法常用于网络编程,可以扩展到其他形式的输入,例如当前案例。

  1. 将标准输入 (STDIN) 句柄 (handle = 0) 放入“观察列表”。
  2. 在观察列表中设置超时。
  3. 只要 STDIN 发生变化,就进行处理。
  4. 超时到期后,检查我们处理的内容是否完成了工作。

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

我不确定我是否可以出于这个问题的目的准确地解释这些概念。作为引用,另一个问题有一些完全相同的代码指针是 here .

<强>2。同步:带中断的多线程 这是一种常用技术,用于我们需要细粒度事件调度程序/计时器的情况。

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

实现相同目的的另一种方法是使操作系统中断线程 B,如 comments 中的一个所述。 .

<强>3。同步:轮询 这用于我们不需要随时间进行过多细粒度控制的情况。

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

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

关于c++ - 在 C++ 中输入超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40811438/

相关文章:

c++ - App::InitInstance() 中的无模式对话框

c++ - 以 headless 模式运行 WinDbg

c++ - 什么是差异 : FillRgn and PaintRgn in win32?

winapi - 进程内和进程外解析 WPAD 有什么区别?

c++ - 使用字符串数组而不是 int 数组实现二进制搜索

c++ - 将字符串传递给 ns3::Ipv4AddressHelper::SetBase 方法

c++ - 透视投影 OPENGL 和计算着色器

python - 如何在 Windows cmd 中传递 *.txt 之类的通配符参数

c++ - 如何将 WndProc 用作类函数

c++ - 在桌面应用程序中托管 Metro 应用程序