Чтобы более четко объяснить, что я хочу делать, я хочу, чтобы мой код проверял, вводит ли пользователь что-то (или если другой файловый дескриптор, чем 0, имеет данные для чтения) каждые (скажем) 2,5 секунды и так до тех пор, пока программа не остановится.Переключение между операторами, если пользователь вводит что-то: бесконечно и с таймаутом
Если пользователь вводит что-либо, простой printf()
уведомит его, а затем программа снова проверит, вводит ли пользователь что-то в течение следующих 2,5 секунд.
Else, он должен просто распечатать, что время закончилось, а затем снова проверить вход пользователя в течение следующих 2,5 секунд.
А вот фрагмент кода я украл из Beej's Guide to Network Programming и модифицирована, чтобы (попытаться) выполнить мои требования:
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#define STDIN 0 // file descriptor for standard input
int main(void){
struct timeval tv;
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(STDIN, &readfds);
tv.tv_sec = 2;
tv.tv_usec = 500000;
while(1){
select(STDIN+1, &readfds, NULL, NULL, &tv);
if (FD_ISSET(STDIN, &readfds)){
printf("A key was pressed!\n");
tv.tv_sec = 2;
tv.tv_usec = 500000;
}else{
printf("Timed out.\n");
tv.tv_sec = 2;
tv.tv_usec = 500000;
}
}
return 0;
}
Пока я не нажимать клавиши, это работает отлично и печатает «тайм-аут. " каждые 2,5 секунды. Но если я что-то введу, то кажется, чтобы игнорировать ввод пользователя и сохраняет печать «Timed out».
С другой стороны, если я объявляю fd_set
и struct timeval
внутри бесконечного цикла, когда я ввожу что-то, это печатает бесконечно, что клавиша была нажата , как будто она игнорирует тайм-аут.
Я понятия не имею, почему такой простой код не работает. Наверное, мне не хватает информации о дескрипторах файлов, о которых я не знаю.
Повторяющийся вопрос - я отслежу его. В принципе, вы должны установить 'readfds' на каждой итерации; 'select()' zaps it. –
@JonathanLeffler, что вы подразумеваете под «настройкой' readfds' на каждой итерации »? Что-то вроде решения @iharob? Я уже пробовал это, но в этом случае программа печатает «ключ был нажат» бесконечно. – TheReader
Что сказал iharob в своем ответе, и что дублирует вопрос в его ответах. После вызова 'select', значение в' readfds' было изменено 'select', в общем, поэтому вам нужно правильно инициализировать его на каждой итерации цикла. –