我想要一个程序,用户有 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 这种方法常用于网络编程,可以扩展到其他形式的输入,例如当前案例。
- 将标准输入 (STDIN) 句柄 (handle = 0) 放入“观察列表”。
- 在观察列表中设置超时。
- 只要 STDIN 发生变化,就进行处理。
- 超时到期后,检查我们处理的内容是否完成了工作。
在 Linux(和许多其他 Unix 风格)中,可以使用 FD_SET
和 select
系统调用来处理监视列表。在 Windows 中,您需要使用 WaitForMultipleEvents
。
我不确定我是否可以出于这个问题的目的准确地解释这些概念。作为引用,另一个问题有一些完全相同的代码指针是 here .
<强>2。同步:带中断的多线程 这是一种常用技术,用于我们需要细粒度事件调度程序/计时器的情况。
- 创建两个线程,
A
和B
。 A
将等待指示的超时时间。B
将等待阻塞读取- 如果
A
在B
完成之前终止(超时),A
会向B
和B 发出信号
决定下一步做什么(终止、重复消息等) - 如果
B
读取密码并且没问题,B
会向A
发出信号并要求它死掉。
实现相同目的的另一种方法是使操作系统中断线程 B
,如 comments 中的一个所述。 .
<强>3。同步:轮询 这用于我们不需要随时间进行过多细粒度控制的情况。
- 使用非阻塞读取检查输入中是否有任何内容 (
kbhit()
) - 如果没有,并且超时还有剩余时间,则等待更短的时间
delta
(比如10ms
) - 如果超时已过且没有更多剩余时间,则执行任何需要的处理(向用户发送消息、退出等)
请注意,在这种情况下,根据 delta
,该方法可能会消耗大量 CPU,并且效率可能很低。例如,如果 delta=10ms
如上所述,线程将每秒被唤醒 100 次并且效率不高,尤其是当用户没有那么快地在键盘上键入字符时。
关于c++ - 在 C++ 中输入超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40811438/