Kann cin nicht auf die Eingabe warten?

8

In einer grafischen Anwendung führe ich Debug-Befehle mit Hilfe der Konsoleneingabe aus. Wenn die Konsole erstellt wird, wird auch ein neuer Thread erstellt, um die Benutzerbefehle zu sammeln, die alle Eingaben verarbeiten. Die grafische Anwendung wird weiterhin parallel ausgeführt. Ich benutze boost :: thread library.

Es funktioniert bisher gut, aber ich habe keine gute Lösung gefunden, um die Ausführung dieses Threads zu stoppen. Der Thread wartet immer auf eine Benutzereingabe:

%Vor%

Wenn die grafische Anwendung endet, werden alle Konsolenfunktionen beendet, in die ich den Thread einschließe:

%Vor%

Wie Sie sehen können, wartet das std :: cin auf Benutzereingaben, nachdem der Join aufgerufen wurde. Eine der Lösungen, die ich ausprobiert habe, ist es, Ereignisse zu erzeugen, die "Tastenanschläge erzeugen", das std :: cin erhält den Wert, den man mit ENTER sendet, der Thread wird schön enden, diese Lösung ist schrecklich und ich möchte sie nicht behalten. Außerdem funktionierte es in einer der Umgebungen, in denen das Tool ausgeführt wird, schlägt aber fehl, wenn ich es zusammen mit einer UI-API verwendete. Könnt ihr mir sagen, wie ich das korrigieren kann? Kann nicht wirklich sicher sagen, ob es in der C ++ - Dokumentation eine Funktion gibt, std :: cin zu stoppen, die auf Benutzereingaben wartet, und einfach und die Programmausführung fortsetzen, ist das überhaupt möglich?

BEARBEITEN: Fein Ich finde, dass keybd_event für einige Umgebungen ein wenig irreführend ist, indem der Eingabehandler mit dem WriteConsoleInput explizit gut funktioniert.

    
notNullGothik 19.12.2011, 23:36
quelle

1 Antwort

1

Ich bin kein großer Windows-Programmierer, ich weiß viel mehr über Unix. Und ich bin total unbekannt mit boost::thread . Das heißt, basierend auf dem Rat an der Unterseite von dies MSDN Seite , hier ist meine Empfehlung:

  • Erstellen Sie zuvor ein Ereignisobjekt Sie erstellen den Konsolenlese-Thread.
  • Wenn Sie herunterfahren möchten, rufen Sie SetEvent für das Ereignisobjekt, unmittelbar bevor die ->join -Methode des Threads aufgerufen wird.
  • Ändern Sie die Hauptschleife in Ihrem Konsolenlese-Thread in WaitForMultipleObjects anstatt istream::operator>> , etwas wie folgt:

    %Vor%
  • Dieser Thread muss dafür sorgen, dass kein anderer blockierender Vorgang als der WaitForMultipleObjects -Aufruf durchgeführt wird. Laut der Diskussion in den Kommentaren bedeutet das, dass processConsoleCommand cin überhaupt nicht verwenden kann. Sie müssen die Low-Level-Konsoleneingabefunktionen verwenden , insbesondere GetNumberOfConsoleInputEvents und ReadConsoleInput , um sicherzustellen, dass Sie nicht blockieren; Sie müssen Zeichen für viele Aufrufe von processConsoleCommand sammeln, bis Sie einen Wagenrücklauf lesen; und du musst auch dein eigenes Echo machen.

zwol 20.12.2011 20:02
quelle