来自命名管道的ifstream-检查是否无阻塞,是否有数据

问题描述

要检查“常规” // You would mostly use process.exit(exitCode); // where exitCode is an integer // or process.kill(processpid); // or process.abort(); 是否有任何待处理的数据,我可以执行以下操作:

std::istream

但是,对于标准输入管道和命名管道,这是不同的。如果我做这样的事情:

bool has_pending_data(std::istream& s) {
  return s.peek() >= 0;
}

永远不会到达else分支,因为执行将在if (has_pending_data(std::cin)) { // process incoming data } else { // do some periodic tasks } 函数上阻塞。有什么方法可以避免对标准输入和命名管道的这种阻塞?

解决方法

问题在于,当std::cin在I / O缓冲区中没有字符时,peek不会返回EOF,而要等到至少写入一个字符。

这是因为iostream库不支持非阻塞I / O的概念。我认为C ++标准中没有任何功能。

此代码可以帮助您检查stdin中数据的存在而不会阻塞:

std::cin.seekg(0,std::cin.end);
int length = std::cin.tellg();
if (length < 0) return; //- no chars available

如果stdin有一些数据-不要忘记将位置重新设置为开始。

std::cin.seekg(0,std::cin.beg);

或者,您可以尝试使用select函数。它通常用于联网,但是如果将stdin的文件描述符传递给它,它将可以正常工作。