Multithread-Konsolen-E / A

8

Ich verwende eine Konsole in meiner Multithread-Anwendung. Im Moment akzeptiert es nur die Ausgabe (printf und ähnliches) und bisher habe ich keine Probleme. Ich möchte jedoch auch Konsoleneingaben unterstützen können, und hier wird mein Leben kompliziert.

Vorwarnend bin ich mit den komplizierteren Nuancen des Arbeitens mit der Konsoleneingabe und -ausgabe sehr vertraut. Meine Erfahrung in dem Thema geht nicht viel weiter als printf / cout, scanf / cin, und mit SetConsoleTextAttribute() , um die Farbe (unter Windows) zu ändern.

Ich würde es vorziehen, mein Programm so kompatibel wie möglich zu halten, aber ich bin nicht dagegen, plattformspezifischen Code schreiben zu müssen, solange ich brauchbare Alternativen für andere Plattformen finden kann.

Konzeptionell möchte ich, dass die Konsole auf ihrem eigenen Thread läuft, so dass sie während des Wartens mit cin gesperrt werden kann, ohne das gesamte Programm oder einen der anderen Threads einzufrieren. Jeder Thread könnte Konsolenausgaben an diesen Thread senden, der ihn sauber ausgibt (wahrscheinlich mit einer threadsicheren Warteschlange), und jede Eingabe, die die Konsole liest, würde den Befehl an den entsprechenden Thread senden.

Mein erstes Problem ist, dass während ich etwas Eingabe tippe, jede Ausgabe mitten in dem, was ich tippe, erscheint. Die Lösung, die ich damit behandeln möchte, wäre, die unterste Zeile der Konsole für die Eingabe zu reservieren und die Ausgabe an die vorletzte Zeile zu senden, die die Eingabezeile nach unten drückt. Wie kann ich das tun?

    
Haydn V. Harach 10.03.2014, 22:49
quelle

3 Antworten

2

Wellp, ich habe es mit pdcurses gelöst. Falls jemand anderes etwas Ähnliches machen möchte, hier ist, wie ich es gemacht habe. Zuerst initialisiere ich die Konsole so:

%Vor%

Als nächstes ist dies die Funktion, die für die Verarbeitung der Ausgabe zuständig ist. Es ist eigentlich sehr einfach, ich muss nichts Besonderes tun, um es threadsicher zu halten. Ich könnte einfach keine Probleme damit gefunden haben, aber eine einfache Lösung wäre, einen Mutex darauf zu schlagen.

%Vor%

Und schließlich, Eingabe. Dieser hat einiges an Feinabstimmung erfordert.

%Vor%

Dies wird jedes Bild aus demselben Thread ausgeführt, der Fenstermeldungen verarbeitet. Ich habe das Blockierungsverhalten von wgetch() unter Verwendung von nodelay() deaktiviert, sodass keine Konsoleneingabe in einem eigenen Thread ausgeführt werden muss. Ich deaktiviere auch Echo und Echo die Eingabe manuell. Durch Aktivieren des Bildlaufs im Eingabefenster kann der Inhalt mit einem einfachen "\ n" gelöscht und durch den Inhalt ersetzt werden, wenn der Benutzer etwas eingegeben hat. Es unterstützt alles, was man von einem einfachen Multi-Threaded-Terminal erwarten kann, das sowohl Eingabe als auch Ausgabe von mehreren Threads empfangen kann.

    
Haydn V. Harach 21.03.2014, 02:54
quelle
2

Sie wollen wirklich nicht die Straße hinuntergehen, um einen Teil der Konsole für die Eingabe zu reservieren, während Sie in den Rest der Konsole schreiben. Zumindest nicht, wenn Sie nur Scroll-Text schreiben. Es ist möglich , aber voller Fehler und viel mehr Ärger als es wert ist. Unter Async Console Output finden Sie einige Hinweise zu den Problemen.

Sicherlich ist es nicht möglich, dies nur mit conio.h zu tun.

Sie können zwei Konsolenbildschirmpuffer reservieren, wobei einer für die Eingabe und einer für die Programmausgabe steht. Wenn Ihr Programm normal läuft, wird der Ausgabebildschirm ausgewählt und Sie sehen die Ausgabe auf dem Bildschirm scrollen. Aber wenn Ihr Programm auf Benutzereingaben wartet, tauschen Sie Bildschirmpuffer aus, so dass die Ausgabe noch läuft, aber im anderen Bildschirmpuffer.

Am Ende müssen Sie die Ausgabe selbst formatieren und WriteConsoleOutput , übergibt es das Handle des Bildschirmpuffers, in den Sie schreiben möchten. Es wird in Eile kompliziert, und es ist sehr schwierig, richtig zu kommen. Wenn es überhaupt möglich ist. Ich weiß, dass ich in der Vergangenheit viel zu viel Zeit damit verbracht habe, und es gab immer seltsame Probleme.

Ich werde nicht sagen, dass das, was Sie tun wollen, nicht möglich ist. Ich werde jedoch sagen, dass Sie eine harte Zeit damit haben werden.

    
Jim Mischel 11.03.2014 02:47
quelle
1

Um Echo-Zeichen zu deaktivieren, überprüfen Sie Folgendes: Ein Passwort von std :: cin lesen

Vielleicht kombinieren Sie das mit Blogpost dieses Kerls auf nicht-blockierender Win32-Konsole io .

Sie könnten dieses Zeug auch nützlich finden: conio.h , pdcurses

    
erapert 10.03.2014 23:18
quelle

Tags und Links