C++ wählen Sie() nicht warten, für den timeout-Zeitraum
Ich versuche, verwenden Sie die Funktion wählen, Eingaben zu übernehmen, aber alle 2 Sekunden etwas anderes zu tun, wenn der Benutzer nicht eingetragen, nichts. Der code unten ist, wartet zwei Sekunden das erste mal select() ist erreicht, aber sobald es druckt die ersten "timed out" Meldung das es schnell halten Ausdruck "timed out", ohne zu warten, für 2 Sekunden, im Grunde in eine Endlosschleife. Wer weiß, was das problem ist? Vielen Dank für jede Hilfe.
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
using namespace std;
const int STDIN = 0;
int main(int argc, int *argv[])
{
struct timeval tv;
fd_set readfds, master;
tv.tv_sec = 2;
tv.tv_usec = 0;
FD_ZERO(&readfds);
FD_ZERO(&master);
FD_SET(STDIN, &readfds);
FD_SET(STDIN, &master);
string buffer = "";
while(buffer != "quit"){
readfds = master;
if(select(STDIN+1, &readfds, NULL, NULL, &tv) == -1) perror("select");
if (FD_ISSET(STDIN, &readfds)){
getline(cin, buffer);
cout << "You entered: " << buffer << endl;
}else
cout << "Timed out.\n" << endl;
}
return 0;
}
Du musst angemeldet sein, um einen Kommentar abzugeben.
pro Mann: select() aktualisiert die timeout-argument, um anzugeben, wie viel Zeit noch übrig war. pselect() ändert sich nicht, dieses argument.
Dies bedeutet, dass, wenn es mal nach 2 Sekunden, es könnte Ihre tv_sec 0.
Wenn die beiden Felder der timeval sind 0 es wird sofort zurück.
Versuchen Sie, Ihren timeout jede Schleife innerhalb der while (), um sicherzustellen, es ist nicht immer überschrieben werden.
Habe ich einige ändern sich je nach code, nach
select
tv
geändert werden.Wenn Sie jemals Lesen Sie die Quelle auswählen.c im linux-kernel, werden Sie feststellen, dass in der select () - Aufruf, der Letzte parameter timeout wird auf null gesetzt, nachdem es verwendet wird.
Also, sollten Sie den Wert des tv innerhalb der Schleife, die vor jedem Aufruf von select().
Wenn der Speicher dient, der Aufruf
select()
können den Wert ändern, dertv
um die Verbleibende Zeit an. Sollten Sie neu initialisierentv
vor jedem Aufrufselect()
.Müssen Sie
in der Schleife. Zuordnung:
readfds = master;
wird nicht immer funktionieren, eigentlich bin ich ziemlich sicher, es wird nicht in jedem Plattform - je nach definitionfd_et
).auch die Einstellung
tv
in einer Schleife ist eine gute Idee.memcpy
zu kopierenfd_set
. Nachdem wiederholt die fd set(s) bit-für-bit für jeden Aufrufselect
ist keine gute Idee.