Для этого вам не нужны pthreads, и вы можете использовать select(2)
или poll(2)
, чтобы узнать, можете ли вы заглянуть в stdin, не блокируя ваше приложение. Для этого я кодировал функцию my_peek()
, которой нужно просто передать количество секунд, в течение которых вы хотите ожидать ввода (вы даже можете передать 0, если не хотите ждать):
/* According to POSIX.1-2001 */
#include <sys/select.h>
/* According to earlier standards */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <iostream>
int
my_peek(unsigned int nsecs)
{
struct timeval timeout;
fd_set rfds;
int fd;
// stdin file descriptor is 0
fd = 0;
timeout.tv_sec = nsecs;
timeout.tv_usec = 0;
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
if (select(fd + 1, &rfds, NULL, NULL, &timeout) > 0)
return std::cin.peek();
return -1;
}
int
main(void)
{
int peek;
peek = my_peek(2);
if (peek != -1) {
std::cout << "we could peek without freezing" << std::endl;
std::cout << "my_peek() returned " << peek << std::endl;
} else {
std::cout << "we could not peek without freezing" << std::endl;
}
return 0;
}
Обратите внимание, что ПЛОХО полагаться на select(2)
, чтобы определить, есть ли данные в объекте cin
или stdin
FILE
, потому что, как сказал Немо, они БУФЕРЫ. Лучшее, что можно сделать, это избежать использования cin в этом примере, используя read(2)
. Улучшенная версия my_peek()
будет выглядеть так:
int
my_peek(unsigned int nsecs)
{
struct timeval timeout;
fd_set rfds;
int fd;
unsigned char c;
// stdin file descriptor is 0
fd = 0;
timeout.tv_sec = nsecs;
timeout.tv_usec = 0;
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
if (select(fd + 1, &rfds, NULL, NULL, &timeout) <= 0)
return -1;
if (read(fd, &c, 1) != 1)
return -1;
return static_cast<int>(c); /* or "return (int)c" for C-only programs */
}
Для получения дополнительной информации, пожалуйста, обратитесь к справочной странице select(2)
по адресу http://linux.die.net/man/2/select.
PS: Вы можете попытаться положиться на значение, возвращаемое std::cin.rdbuf()->in_avail()
, как описано на сайте cpluplus http://www.cplusplus.com/reference/iostream/streambuf/in_avail/, или даже в методе readsome()
класса istream
, но они обычно зависят в буфере FILE
, который не доступен в библиотеке GNU C ++. Не делайте этого, иначе вы можете потерпеть неудачу.