Wie asynchron liest man Eingabe von der Kommandozeile mit Boost Asio in Windows?

8

Ich habe diese Frage gefunden, die fragt, wie man asynchrone Eingaben liest, aber nur Arbeiten Sie mit POSIX-Stream-Deskriptoren, die unter Windows nicht funktionieren. Also habe ich dieses Tutorial gefunden, das zeigt, dass anstelle eines POSIX Stream Descriptor Ich kann ein boost::asio::windows::stream_handle verwenden.

Nach beiden Beispielen kam ich auf den folgenden Code. Wenn ich es ausführe, kann ich nichts in die Eingabeaufforderung eingeben, da das Programm sofort beendet wird. Ich möchte, dass es jede Eingabe vom Benutzer erfasst, möglicherweise in eine std::string , während andere Logik in meinem Programm ausgeführt werden kann (d. H. Asynchrone I / O von einer Windows-Konsole ausführen).

Im Wesentlichen versuche ich zu vermeiden, mein Programm zu blockieren, wenn es versucht, von stdin zu lesen. Ich weiß nicht, ob das in Windows möglich ist, da ich auch diesen Beitrag gefunden habe Details zu Problemen, mit denen ein anderer Benutzer bei der gleichen Vorgehensweise konfrontiert wurde.

%Vor%     
nickb 21.10.2011, 20:59
quelle

3 Antworten

3

Ich habe gerade ein oder zwei Stunden damit verbracht, dieses Thema zu untersuchen, also habe ich beschlossen zu schreiben, um andere daran zu hindern, ihre Zeit zu verschwenden.

Windows unterstützt IOCP für standardmäßige Eingabe- / Ausgabehandles nicht. Wenn Sie das Handle von GetStdHandle(STD_INPUT_HANDLE) übernehmen, enthält das Handle FILE_FLAG_OVERLAPPED nicht, sodass es überlappende (asynchrone) IO nicht unterstützt. Aber selbst wenn du

%Vor%

WinAPI ignoriert dwFlagsAndAttributes und gibt das Handle zurück, das überlappende IO nicht unterstützt. Die einzige Möglichkeit, asynchrone IO der Konsoleneingabe / -ausgabe zu erhalten, besteht darin, das Handle mit WaitForSingleObject mit 0-Timeout zu verwenden, damit Sie überprüfen können, ob etwas nicht blockierend gelesen werden kann. Nicht genau async IO aber kann Multithreading vermeiden, wenn es ein Ziel ist.

Weitere Details zur Konsolen-API: Ссылка

Was ist der Unterschied zwischen Handles, die von GetStdHandle und CreateFile zurückgegeben werden, wird hier beschrieben: Ссылка . Kurz gesagt ist der Unterschied nur für einen untergeordneten Prozess, wenn CreateFile Zugriff auf seinen Konsolen-Eingabepuffer geben kann, selbst wenn er im übergeordneten Prozess umgeleitet wurde.

    
Andriy Tylychko 24.09.2015, 10:46
quelle
5

Sie müssen io_service::run() auf starten die Ereignisverarbeitungsschleife für asynchrone Operationen.

%Vor%     
Sam Miller 21.10.2011 21:37
quelle
3

Sie müssen Ihren stream_handle mit dem Konsoleneingabe-Handle initialisieren. Sie können nicht denselben stream_handle für die Eingabe und für die Ausgabe verwenden, da dies zwei verschiedene Handles sind.

Für die Eingabe:

%Vor%

Für die Ausgabe würden Sie CONSOLE_OUTPUT_HANDLE verwenden. Aber das ist wahrscheinlich zu viel Aufwand, Sie werden wahrscheinlich nicht so viele Daten in Windows ausgeben, dass Sie einen asynchronen Schreibvorgang benötigen.

    
SoapBox 21.10.2011 21:21
quelle

Tags und Links