std::cin und std::cout parallel nutzen



  • Guten Morgen,
    Ich habe bereits gestern recherchiert, aber nichts Brauchbares zu meinem Problem gefunden. Daher hoffe ich nun, hier eine Antwort zu finden, obwohl ich nicht glaube, dass sich mein Problem mit der STL lösen lässt.

    Aber nun zu meinem Problem:
    Ich habe in meinem Programm zwei Threads. Der eine Thread muss mittels cout Daten in die Konsole schreiben. Dies ist keine Reaktion auf Benutzerangaben!
    Der Benutzer muss gleichzeitig aber auch in der Lage sein, Daten einzugeben, die ich dann mit cin abfragen kann.
    Wenn ich nun etwas eingebe und der andere Thread schreibt beispielsweise "Hallo", dann steht in meinem geschriebenen Text "Hallo". Das "Hallo" lässt sich nicht löschen, aber die Eingabe landet korrekt in cin.

    Dies ist natürlich nicht das gewünschte Ergebnis!

    Optimal wäre es wenn cout automatisch die Daten ÜBER meine eigenen Eingaben schreiben würde und nicht in meine Eingabe hinein.

    Ich hoffe, dass ich mein Problem ausführlich genug beschrieben habe. Code dazu habe ich leider noch nicht, da ich mich momentan noch in der Planungsphase befinde.

    Vielen Dank schon mal jetzt für eure Antworten!

    SALOMON



  • theoretisch müsstest du dir die cursorposition merken wo du bei der eingabe grad bist, den cursor eine zeile höher setzen die cout machen und dann den cursor wieder an die alte position setzen.
    klingt aber n bissgen heftig muss ich sagen, sicher das du nur konsole benutzen kannst ?



  • cin/cout schreiben standardmäßig direkt auf den Monitor (cout die Daten, die es bekommen hat, cin (indirekt) das Bildschirmecho zu deinen Eingaben), das wirst du nur schwer trennen können. Eine Lösung zu deinem Problem wäre Thread-Synchronisation über Mutexe oder Semaphore: Du legst einen Mutex an, der von beiden Threads reserviert wird, bevor sie lesen/schreiben dürfen. Dann muß der Arbeitsthread warten, bis der Nutzer fertig ist mit der Eingabe, bevor er seine Meldungen schreiben darf.



  • Ich hab mal versucht die Cursor mit tellg und tellp (cin und cout) auszulesen. Da kam aber nur -1 raus...

    Ich habe mir auch überlegt das evtl. mit WinAPI zu machen, aber ich wollte das zuerst mit der STL versuchen 😉

    @CStoll:

    Ja das hab ich mir auch gedacht. Aber der Punkt ist, dass die Ausgaben keine Reaktion auf Benutzereingaben sind!
    Wenn ich also die Ausgabe sperre, bis der Nutzer etwas eingegeben hat, dann gibt es auch keine Ausgabe, wenn der Benutzer nichts eingibt...



  • SALOMON schrieb:

    Ich hab mal versucht die Cursor mit tellg und tellp (cin und cout) auszulesen. Da kam aber nur -1 raus...

    Klar, an die Cursor-Position auf dem Monitor kommst du mit Standard-Mitteln auch nicht heran. Dazu benötigst du Spezialbibliotheken (WinAPI, ncurses, Improved Console).



  • ich frag mal von ner anderen seite, wieso müssen es den 2 threads sein? schreibt der eine informationen während der andere auf die eingabe wartet ?
    oder soll das evtl. ne art konsolenchat werden ?
    wenn es was komplexeres wird und du wert auf die aktuellsten daten legst benutz eventuell wxwidgets oder gleich nen compiler mit gui.



  • Genau getroffen 😉

    Es soll ein Chat werden.
    Ich dachte, dass das mit der Konsole keine schlechte Idee wäre. Ich habe auch die Möglichkeit, das Programm mit der WinAPI zu realisieren, aber die Konsole hat mich in dem Moment doch sehr gereizt 🙂

    Wäre es denn möglich, so etwas mit z.B. ImprovedConsole zu erstellen?



  • puah, ich arbeite nur mit gui, weil multithread auf der konsole iss doch bissl pöhse.
    versuchs doch lieber mit einem thread, poll den socket mit select und timeout.u_sec = 5000; dann ein getch() (oder wie der nochmal hiess der ein zeichen des eingabepuffer liesst ohne zu blockieren) mach das echo an die gewünscht stelle (am besten paralel ind einen speicherstringschreiben) und dann lausch wieder am socket.

    nochmal zum mitmeiseln:

    while(!ende){
      if (select(5ms)) {
        cout ; // an gewünschter stelle
      }
      char input;
      input = getch;
      while (input != 0){
        echo in die unterste zeile der konsole;
        oder send(Socket, nachricht) wenn input == enter;
      }
    }
    


  • Möglich sicher, aber vermutlich recht komplex (vor allem mußt du ständig zwischen Lese-Cursor (für Nutzer-Eingaben) und Schreib-Cursor (für die Ausgaben) umschalten).

    *grübel* Mal ein Psudocode-Ansatz dafür:

    //Eingabe an Position xp/yp
    
    Mutex M;//für Synchronisation
    
    string input(int xp,int yp)
    {
      char c=0;
      string ret="";
      do
      {
        if(kbhit())
        {
          M.lock();
          gotoxy(xp+ret.length(),yp);
          c=getch();
          ret+=c;
          M.unlock();
        }
      }
      while(c!='\n');
      return ret;
    }
    
    //Schreiben an Position xp/yp
    void output(int xp,int yp,const string& text)
    {
      M.lock();
      gotoxy(xp,yp);
      cout<<text;
      M.unlock();
    }
    

    Jetzt mußt du nur noch dafür sorgen, daß sich die beiden Funktionen nicht gegenseitig den Bildschirm überschreiben, indem du die Koordinaten geeignet auswählst.



  • Wie schon gesagt, ich habe damit schon gerechnet, dass sich das mit reiner STL wohl schlecht realisieren lassen würde.
    Danke für den Vorschlag, aber ich werde den Thread trotzdem brauchen. Ich werde das Programm dann lieber mit Hilfe der WinAPI erstellen.

    Danke für die Antworten!



  • Wow!
    Ich wollte im vorherigen Post zuerst noch dazu schreiben: "Vielleicht fällt jemandem dazu noch was ein". Der Code sieht doch sehr gut aus! Ich werde mir das heute Nachmittag mal ansehen!

    Vielen Dank



  • Ich bin mir nicht sicher, aber könnte vielleicht ein Hook weiterhelfen?
    Ansonsten gibt es ja auch Frameworks die es ermöglichen eine Möchtegern-GUI auf der Konsole darzustellen (wie es bei COBOL oft gemacht wurde ^^), vielleicht ist es ja mit sowas möglich. Dann muss man evtl. nicht alles selbst machen.

    Ich habe bei meinem IRC-Client auch GUI bevorzugt, ist recht bequem zu programmieren. 🙂

    Greetz


Anmelden zum Antworten