我写了程序
#include<iostream>
using namespace std;
int n;
int main(int argc, char *argv[])
{
std::cout << "Before reading from cin" << std::endl;
// Below reading from cin should be executed within stipulated time
bool b=std::cin >> n;
if (b)
std::cout << "input is integer for n and it's correct" << std::endl;
else
std::cout << "Either n is not integer or no input for n" << std::endl;
return 0;
}
这里std :: cin语句将等待控制台输入并进入睡眠模式,直到我们提供一些输入并按Enter键。
我希望std :: cin语句在10秒后超时(如果用户在10秒之间没有输入任何数据,那么编译器将开始执行std :: cin语句下面的程序的下一个语句。
我能够使用多线程机制解决它。以下是我的代码:
#include<unistd.h>
#include<stdlib.h>
#include<pthread.h>
#include<iostream>
using namespace std;
void *thread_function(void *arg);
int input_value;
int main(int argc, char *argv[])
{
int res;
pthread_t a_thread;
void *thread_result;
res=pthread_create(&a_thread,NULL,thread_function,NULL);
if(res!=0){
perror("Thread creation error");
exit(EXIT_FAILURE);
}
//sleep(10);
cout<<"cancelling thread"<<endl;
res=pthread_cancel(a_thread);
cout<<"input value="<<input_value<<endl;
exit(EXIT_SUCCESS);
}
void *thread_function(void *arg)
{
int res;
res=pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
if(res!=0){
perror("Unable to set pthread to cancel enbable state");
exit(EXIT_FAILURE);
}
cin>>input_value;
pthread_exit(&input_value);
}
但在这里我遇到了一个问题。由于睡眠功能要么用户输入值,要么睡眠功能默认睡眠10秒。这是我滞后的地方。
如何使用(信号,二进制信号等等)来解决这个问题。请将您的答案与我的解决方案(即多线程)联系起来。
欢迎提供任何信息......
答案 0 :(得分:5)
由于你在POSIX机器上,你可以使用例如select
检查标准输入上是否有任何内容:
fd_set fds;
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds)
timeval timeout;
timeout.tv_sec = 5; // A five-second timeout
timeout.tv_usec = 0;
int rc = select(STDIN_FILENO + 1, &fds, nullptr, nullptr, &timeout);
if (rc < 0)
perror("select");
else if (rc == 0)
{
// Timeout
}
else
{
// There is input to be read on standard input
}
使用poll
(由Basile Starynkevitch建议)可以这样做:
struct pollfd poller;
poller.fd = STDIN_FILENO;
poller.events = POLLIN;
poller.revents = 0;
int rc = poll(&poller, 1, 5); // Poll one descriptor with a five second timeout
if (rc < 0)
perror("select");
else if (rc == 0)
{
// Timeout
}
else
{
// There is input to be read on standard input
}
答案 1 :(得分:1)
我已经尝试了一些解决方案来实现这一点,而我当前的解决方案非常糟糕,但是,它适用于我使用select和poll的其他解决方案失败的地方。
我的代码有时会为数据提供正面结果,但会在std::cin.get();
或std::getline(std::cin, STRINGVARIABLE);
我的解决方案:
// Reset flag, initially true so that if cin blocks it will be reset
bool Reset = true;
// Create a c++11 thread to reset cin after a timeout of 100ms
std::thread ResetThread([&Reset](void){
// This thread will wait 100ms
std::this_thread::sleep_for(std::chrono::milliseconds(100));
// Then if the reset flag is still true it will reset cin by closing and opening it
if (Reset) {
close(STDIN_FILENO);
// TODO: Really the output of this open call should be checked for errors
open("/dev/null", O_RDONLY);
}
});
// Now for the standard reading of cin:
std::string Line;
std::getline(std::cin, Line);.
// If cin was read correctly the getline command will return immediately
// This means that the reset flag will be set to false long before the thread tests it.
Reset = false;
// Finally join with the thread.
ResetThread.join();
此代码可以与select或poll方法(在我的代码中)连接,以防止每100ms创建一个新线程。
显然,此代码的适当性取决于项目的其余部分,但它对我有用,所以我想我会分享。
- 编辑 -
在PC之间移动之后,似乎这段代码并不像我希望的那样强大。我现在只接受使用单独的阻止线程进行输入,请参阅我的答案:
在与非阻塞cin战斗很长一段时间之后,似乎唯一可行的方法是在自己的线程中。
请参阅我的答案以获得实施: