Hilfe bei Atomics benötigt



  • Ihr könntet auch einfach konkret werden, das würde alles wesentlich vereinfachen.

    Edit: Zu spät.



  • Wieso benutzt Du nicht einfach strands? Bei boost.asio ist das eigentlich der natürliche Weg, um Resourcen gegen Races zu schützen. Das bedeutet natürlich auch, dass Du dich von den synchronen Operationen verabschieden musst, aber das sollte man bei boost.asio eh.



  • strands verhindern doch Parallelität. Das ist Mist.

    @SoM: Also, hier goes:
    Es gibt Channel und User. :p
    In jedem Channel können beliebig viele User sein (auch 0). Wenn sich ein User zum Server connected, wird eine asynchrone Lese-Operation gestartet. Sobald der User etwas sendet, wird von einem der Server-Threads ein Handler aufgerufen, der die Nachricht verarbeitet. Wenn an einen User mehrere Nachrichten aus verschiedenen Threads gesendet werden sollen, gibt es immer einen besitzenden Thread, der schreibt. Die Anderen Threads werfen ihre Nachrichten für den besitzer-Thread in eine Queue, die von ihm abgearbeitet wird.



  • Kellerautomat schrieb:

    strands verhindern doch Parallelität. Das ist Mist.

    Synchronisieren verhindert parallelität. Entweder Du musst synchen, oder eben nicht. Was denn nun?



  • Ein strand sorgt dafür, dass niemals zwei Handler zur selben Zeit aufgerufen werden. Wozu habe ich dann mehrere Threads, wenn die eh nicht parallel aufgerufen werden? Das ist einfach fail per Design.



  • Kellerautomat schrieb:

    Ein strand sorgt dafür, dass niemals zwei Handler zur selben Zeit aufgerufen werden. Wozu habe ich dann mehrere Threads, wenn die eh nicht parallel aufgerufen werden? Das ist einfach fail per Design.

    Du sollst ja auch nicht pauschal alle Handler durch einen Strand jagen, sondern nur die, in denen auf geteilte Ressourcen zugegriffen wird.

    In Deinem Fall brauchst Du z.B. in Deinem (nicht über einen Strand synchroniserten) Accept-Handler sowas wie:

    void server::handle_accept(boost::system::error_code const & ec)
    {
    	client_ptr_t new_client(new client(socket)); //client erzeugen
    	//...
    	//neben remove_client die einzige operation die vermutlich durch den strand gehen muss...
    	acceptor.get_io_service().post(strand.wrap(boost::bind(&server::enlist_client, this, new_client)));
    }
    


  • Kellerautomat schrieb:

    In jedem Channel können beliebig viele User sein (auch 0). Wenn sich ein User zum Server connected, wird eine asynchrone Lese-Operation gestartet. Sobald der User etwas sendet, wird von einem der Server-Threads ein Handler aufgerufen, der die Nachricht verarbeitet. Wenn an einen User mehrere Nachrichten aus verschiedenen Threads gesendet werden sollen, gibt es immer einen besitzenden Thread, der schreibt. Die Anderen Threads werfen ihre Nachrichten für den besitzer-Thread in eine Queue, die von ihm abgearbeitet wird.

    Folgende Fragen: warum mehrere Threads? Wonach werden die erstellt?
    Wonach wird der Besitz des Sockets entschieden?
    Wonach wird entschieden welcher Thread vom Socket liest?



  • Shade Of Mine schrieb:

    Folgende Fragen: warum mehrere Threads? Wonach werden die erstellt?
    Wonach wird der Besitz des Sockets entschieden?
    Wonach wird entschieden welcher Thread vom Socket liest?

    Das macht asio für Dich. Du startest in mehreren Threads io_service::run für das gleiche io_service -Objekt, und und asio sorgt dann dafür, dass aktivierte Handler auf freie Threads verteilt werden.



  • Shade Of Mine schrieb:

    warum mehrere Threads?

    - Damit der Server besser skaliert
    - Weil ich Erfahrungen mit Threads sammeln will

    Shade Of Mine schrieb:

    Wonach werden die erstellt?

    In der Config lässt sich einstellen, wie viele Threads der Server verwenden soll.

    Shade Of Mine schrieb:

    Wonach wird der Besitz des Sockets entschieden?

    Der schnellste Thread gewinnt.

    Shade Of Mine schrieb:

    Wonach wird entschieden welcher Thread vom Socket liest?

    Das macht boost.asio für mich.



  • Alles klar.

    Dann ist das eine Frage des asio Handlings. Da gibts sicher etwas das genau dafür gemacht wurde.



  • Mir ist da gerade was in den Kopf gekommen, wovon ich vermute, dass ich es euch nicht so verdeutlicht habe. Also: Der Besitzer des Sockets gilt nur für eine Gruppe an Schreibvorgängen. Sobald diese abgeschlossen sind, gibt es keinen Besitzer mehr. Bei jeder neuen Gruppe wird ein neuer Besitzer gewählt.



  • Shade Of Mine schrieb:

    genau dafür

    Wofür?



  • Kellerautomat schrieb:

    Shade Of Mine schrieb:

    genau dafür

    Wofür?

    Zum Synchronisieren...



  • Vielleicht solltest du erstmal 'nen Chatclient ohne boost::asio schreiben, mit ganz normalen listen , accept , etc. . Schon 6 Seiten ohne Trolling und vieles ist noch unklar. Vielleicht hilft auch: http://www.c-plusplus.net/forum/304133 .


Anmelden zum Antworten