Nicht blockierende Eingabe (Konsole)



  • Hi,

    Gegenfrage: Was ist ACE?

    Ich kenn zwar ACE als Kompressionsalgorithmus, aber das hat hiermit ja wohl nichts zu tun.

    Ist das eine Cross-Platformlib für Sockets?

    Aber jetzt noch eine Frage: Kann auch ein Singlethreadedserver mit select() bzw. asynchronen Sockets schnell genug sein oder muss es wirklich Multithreading sein?

    ChrisM



  • The ADAPTIVE Communication Environment (ACE) is a freely available, open-source object-oriented (OO) framework that implements many core patterns for concurrent communication software. ACE provides a rich set of reusable C++ wrapper facades and framework components that perform common communication software tasks across a range of OS platforms. The communication software tasks provided by ACE include event demultiplexing and event handler dispatching, signal handling, service initialization, interprocess communication, shared memory management, message routing, dynamic (re)configuration of distributed services, concurrent execution and synchronization.

    ACE is targeted for developers of high-performance and real-time communication services and applications. It simplifies the development of OO network applications and services that utilize interprocess communication, event demultiplexing, explicit dynamic linking, and concurrency. In addition, ACE automates system configuration and reconfiguration by dynamically linking services into applications at run-time and executing these services in one or more processes or threads.

    http://www.cs.wustl.edu/~schmidt/ACE.html



  • Hi,

    ich muss sagen, das Teil sieht ja richtig gut aus und scheint mir auch noch bei einigem mehr zu helfen als nur bei asynchronen Sockets.

    Nur weiß ich jetzt immer noch nicht, ob der Speed dann reicht oder ob ich, wenn ich vernünftige Pings haben will, auch bei hundert oder mehr Spielern, doch mehrere Threads verwenden muss. Denn ich habe keine Lust jetzt drauflos zu coden und dann am Ende festzustellen, dass ich alles nochmal umschreiben muss. 😉

    ChrisM



  • Hi,

    sorry, dass ich das hier nach einem Monat immer noch pushen muss, aber ich habe für beide Probleme noch keine Lösung gefunden:
    1. Kann ein select()-Server genauso schnell sein wie das Multithreadingäquivalent?
    2. Wir krieg ich jetzt nicht-blockierende Eingabe ohne Zerhackstückselung der Ausgabe in der Konsole hin? Gar nicht?

    ChrisM



  • Hi,

    bitte helft mir doch, auch wenn der Thread hier langsam (nicht nur euch) nervt, aber das kann doch nicht sein, dass hier noch keiner einen Server geschrieben hat, oder doch?

    ChrisM



  • Ach komm, so schwer ist das doch garnicht.
    Du machst mehrere Threads, einer verwaltet die Ausgabe, einer die Eingabe, einer den Rest. Der Ausgabethread schläft.

    Wenn jemand was ausgeben will, dann gibt er das was auszugeben ist an den Ausgabe-Thread (einfach irgendwo in nen Puffer reinhängen), dann weckt er den Ausgabethread auf. Und der schaut nach, ob die Konsole grad frei ist, falls ja markiert er sie als besetzt und gibt seine Daten aus, danach wieder freigeben und legt sich wieder schlafen.

    Das solltest Du mit ner Semaphore machen, weil sonst evtl. Aufweck-Signale verloren gehen.

    Sobald ne Eingabe kommt übernimmt die der Eingabethread und setzt die Konsole auf blockiert. Dann wird gewartet, bis Du mit Return bestätigst, dadurch gibst Du die Konsole wieder frei und weckst den Ausgabethread auf, ob er was zum Ausgeben hat in der Zwischenzeit.

    Alternativ hätte ich auch noch ne viel einfachere Lösung:

    Mach die Konsole nur als Anzeige und ne Eingabezeile.
    Wenn also neue Messages kommen, dann werden die einfach angehängt und Deine Eingabezeile bleibt unten fest stehen. Erst wenn Du Enter drückst wird das ganze Ausgegeben und damit in die restlichen Meldungen eingereiht.
    Aber wirklich portabel wird das wahrscheinlich auch nicht.

    MfG Jester



  • Hi,

    ok, soweit ist das klar, vielleicht kann ich auf den Ausgabethread ja sogar verzichten.

    Jetzt geht es nur noch darum, ob es sich lohnt oder ob es der Performance eher schadet, für jeden Client einen eigenen Thread zu machen. Leider kann ich nicht mal eben einen Test mit genug Clients durchführen, um das zu testen. 😞

    ChrisM



  • Hi,

    gleich nochmal eine Frage zu Threading: Wie kann ich Multithreading portabel implementieren, ohne eine Lib zu verwenden?

    Geht das überhaupt (vielleicht gibt's ja POSIX-Funktion...) oder muss ich das mit bedingter Compilierung lösen?

    ChrisM



  • Es gibt ne POSIX-API für Threads, aber willkommen bei MS: Windows hat die AFAIK nicht implementiert. Also entweder doch ne Lib oder bedingte Kompilierung bzw. Eine Schnittstelle definieren und dann mehrmals implementieren.

    Auf den Ausgabethread würd ich übrigens nicht verzichten, weil Dein Programm sonst, wenn es eine Ausgabe machen will und die Konsole gerade durch die Eingabe blockiert ist warten muß, bis es weiter gehen kann.
    Du könnetst höchstens versuchen Ein/Ausgabe in einem Thread unterzubringen.
    Das könnte auch eine ganze gute Lösung sein, zumal Du dann einige Synchronisationsprobleme los wirst.

    MfG Jester



  • Für Threads würde ich boost::thread nehmen (www.boost.org). Da man boost sowieso an allen Ecken und Enden brauchen kann, ist es IMHO kein sinnvolles Ziel, bei den Bibliotheken zu sparen.

    Und ich habe schon Server geschrieben, allerdings hatten die keine Eingabe. Und wenn, dann waren es eh Windows-Anwendungen mit einer ListBox und einem Edit, und Multithreading bin ich mit asynchronen Sockets auch aus dem Weg gegangen. Bist du sicher, dass du all die Portabilität wirklich brauchst? Wenn eine plattformunabhängige Lösung mehr Arbeit ist als jeweils eine für alle Zielplattformen zu schreiben, dann kann mans auch sein lassen 🙂



  • Hi,

    naja, portabel sollte es schon sein. Der Client muss ja net unter Linux laufen, aber der Server sollte das schon.

    Aber das was ich jetzt noch momentan mache (mit select()), ist es ja quasi wie mit asynchronen Sockets. Nur bezweifle ich, dass das schnell genug ist.

    Für die Threads werd' ich dann doch Boost verwenden, jetzt muss ich nur noch wissen, was schneller ist und dann geht es los:
    - select() mit Timeout 0 (Polling)
    - Thread für jede Verbindung und Blocking Calls

    ChrisM



  • Ich weiß nicht ob es sinnvoll ist für jeden User einen Thread zu fahren. Das macht die Sache jedenfalls schwieriger. Wie wäre es mit einem Worker-Thread und eben einem oder zwei Threads für Ein/Ausgabe, die dann aber die meiste Zeit schlafen, also nur in den seltenen Fällen einer Ein/Ausgabe Rechenzeit benötigen. Damit ist es die meiste Zeit, als hättest Du nur den Workerthread laufen.



  • Hi,

    ja, aber dann muss ich im Workerthread ja zwangsläufig select() oder asynchrone Sockets verwenden (eher select(), weil das portabel ist) und mir wurde gesagt, dass z.B. auch send() Zeit braucht und das wäre halt blöd, wenn dann immer der ganze Hauptthread in der Zeit nix anderes machen kann.
    Nur weiß ich net, ob der Zeitverlust kleiner ist als der durch die Massen an Threads. (mit 100 Clients könnt ihr rechnen... 😉 )

    ChrisM



  • hm, nochmal zu dem Zerstückelungsproblem, tut mir leid, wenn das mittlerweile nicht mehr gefragt ist,

    aber in den Programmen, die ich kenne, hat man für die Eingabe ein eigenes Feld, die Ausgaben kommen in ein anderes Feld. Da kann dann auch nix zerstückelt werden...



  • @ChrisM:

    Da wirst Du wohl mal ausprobieren müssen. Du könntest ja auch ein hybrides Modell bauen: Jeder Workerthread managed bis zu 10 Clients, immer wenn alle voll sind wird für den nächsten ein neuer Thread gestartet.
    Dadurch kannst Du viele Clients bedienen und hast trotzdem nicht ganz so viele Threads.



  • Hi,

    *** schrieb:

    aber in den Programmen, die ich kenne, hat man für die Eingabe ein eigenes Feld, die Ausgaben kommen in ein anderes Feld. Da kann dann auch nix zerstückelt werden...

    ja, aber wie macht man sowas, ohne cout/cin usw. neuzuschreiben?

    ChrisM



  • Kann ein normales Linux wirklich *keine* asynchronen Sockets?! select ist eine der fragwürdig designtesten Funktionen, der ich je begegnet bin... (Ja, ich komme nicht viel rum 😉 ).



  • Hi,

    was findest du an select() so schlecht? Ich find select() vom Prinzip her zum Pollen (also sofortige Rückkehr ohne Warten) gut geeignet, nur hab' ich halt oft gehört, dass es nicht grade schnell sein soll.

    Ich werde jetzt vorerst bei select() bleiben und später dann schauen, ob ich doch Threads verwende.

    ChrisM


Anmelden zum Antworten