Maximale Anzahl (p)threads?



  • Hi,

    ich verstehe nicht so ganz, wozu du jedesmal einen Fred aufmachen willst. Hast Du 2^31 Netztwerkkarten? Du hast doch in jedem Fall eine Engstelle, durch die es nur langsam und seriell durchgeht, und das ist der Netzzugriff. Das ist wie mit der Baustelle auf der Autobahn. Es bringt für den Gesamtdurchsatz nichts, wenn Du von 6 Spuren auf 8 Spuren erweiterst, wenn am Ende eine einspurige Baustelle ist. Genau so ist es mit Deinem Problem. Das langsamste ist sowieso das Netz, und das ist nunmal seriell.

    Gruß Mümmel



  • @muemmel:
    Die Netzwerkkarte ist hier sicher nicht die Engstelle, denn es dauert unheimlich lange bis so ein Server im Internet antwortet.
    Und das Netz ist nicht in dem Sinn "seriell" dass man nicht mehrere Requests an mehrere Server gleichzeitig ausständig haben könnte. Das wäre ja ne Katastrophe wenn das nicht ginge. Es macht also durchaus Sinn quasi gleichzeitig mehrere Requests abzusetzen. Die Frage ist nur das wie, also ob mit Threads oder asynchronem IO oder nonblocking IO oder...



  • Hi,

    ist mir schon klar, daß die eigentliche Antwort viel langsamer ist als die Netzwerkkarte, denn die kann ja problemlos die volle vom Protokoll mögliche Datenrate.
    Aber INNERHALB Deines Rechners ist die Netzwerkkarte mit Sicherheit das langsamste Teil, denn sie muß von der heutezutage doch recht gewaltigen Geschwindigkeit des Prozessors runter auf das vergleichsweise langsame Tempo des Netzes transformieren.
    Sicher, das Netz selber ist nicht seriell, aber die Netzwerkkarte schon. Da geht immer nur ein Paket nach dem anderen durch. Was bringt es da, wenn die einzelnen Prozesse Schlange stehen, und warten bis sie was zu tun bekommen.
    Nicht vergessen, daß ein zusätzlicher Fred immer wesentlich mehr Overhead hat als nur einfach eine Funktion aufrufen. Wenn mehrere Prozesse, dann höchstens dahingehend, daß einer Deine Netzwerkkarte abfragt und wenn was da ist das dann an den zweiten übergibt zum Verarbeiten. Aber viele Prozesse starten lohnt schon deshalb nicht, weil Deine Maschine mit hoher Wahrscheinlichkeit nicht mehr als maximal 4 Kerne hat. Du vertust also im Endeffekt die Zeit blos damit, die Maschine von Fred zu Fred springen zu lassen statt zu arbeiten.
    Einen wirklichen Sinn macht es nur dann, wenn dadurch die eigentliche Programmierung für Dich einfacher und übersichtlicher wird. Aber leisungsmäßig holst Du da bestimmt nichts raus.

    Gruß Mümmel



  • muemmel, deiner Argumentation kann ich nicht ganz folgen. Vor allem was die Netzwerkkarte angeht. Dass mehrere Threads/Prozesse wohl nicht die beste Lösung ist wurde schon mehrfach geschrieben, hat aber mit der Netzwerkkarte nun garnix zu tun. Genauso eigentlich nicht mit der Zeit die beim Context-Switching draufgeht. Deine Argumentation "brauchste eigentlich garnicht" was Threads angeht lässt sich auch auf viele Bereiche anwenden wo oft Threads eingesetzt werden weil es einfach praktisch ist.



  • @muemmel dir ist schon klar, dass man die Übertragungsgeschwindigkeit einer Netzwerkkarte/-verbindung durch die Bandbreite misst und 60*40=2400Bytes quasiparallel übertragen werden (zusätzliche Bandbreite durch Ethernet, IP und TCP vernachlässigt).



  • Nun muss ich doch fragen, was hier nicht stimmt:

    // (foreach client (c_itr)
    				*c_itr = new Client(s_itr->ip.c_str(), s_itr->port, eUDP);
    
    		// (foreach client (c_itr)
    			(*c_itr)->send("\\status\\",8);
    
    		sleep(3); // TIMEOUT
    	        // (foreach client (c_itr)
                    {
    			char buffer[1024];
                            (*c_itr)->recv(buffer, 1024);
    			puts("done...");
                    }
    
    		// (foreach client (c_itr)
    			delete *c_itr;
    

    Das ist jetzt mehr oder weniger Pseudo-Code. Zuerst connected er zu allen servern der Reihe nach, danach sendet er der Reihe nach jedem Server eine Message. Dann sollte er nach 3 Sekunden von jedem Server die Response empfangen.

    Allerdings hängt er nach ca. 10 von 100 Servern beim recv() fest (dieses Client::recv() macht vorher einen select()-call mit Timeout - aber das Timeout wird hier überschritten und es passiert nichts)...

    Geht das so überhaupt? Kann ich hundert Servern nen Request schicken, so dass die alle ihre Nachrichten auf meinem Socket "speichern"? Ist der Speicherplatz meines Sockets vielleicht begrenzt? (Die Antworten müssten zusammen ca. 30 kb groß sein).

    BTW: Wireshark sagt mir auch nur, dass alle 100 send-Befehle geklappt haben, aber nur die ca. 10 erwähnten Nachrichten eingegangen sind.



  • Da es hier vermutlich sowieso um Linux geht eigetlich hinfällig aber:

    Windows läßt nur eine bestimmte anzahl gleichzeitiger verbindungen zu solange man es nicht in der Registry ändert.
    IMHO bei XP 10.



  • Windows läßt nur eine bestimmte anzahl gleichzeitiger verbindungen zu solange man es nicht in der Registry ändert.
    IMHO bei XP 10.

    Du meinst das Half-Open Connection Limit.



  • Jo das meint er, und das lässt sich gottseidank patchen.

    Man guckt im Event-Log nach dem Eintrag, notiert sich die EventID, sucht damit im Google -> findet den Patch -> lädt ihr herunter -> installiert ihn -> hat Ruhe. Oder so ähnlich 🙂

    @voidpointer:
    Wenn du recv nur auf die Sockets versuchst wo select() auch hingehaut hat, dann sollte es gehen. Wenn du bloss vorher select() machst und dann trotzdem auf alle Sockets ein recv machst ist es klar dass es blockieren wird.



  • Hmm die Frage die ich eigentlich hatte war:
    -Wenn der Server etwas send()et, aber der Client erst 3 Sekunden später recv()ed... wo werden die zwischengespeichert?
    -Könnte es passieren, dass alle Messages, die noch nicht empfangen wurden, aber schon vom Server geschickt wurden, auf irgendeinem Buffer beim Client gespeichert werden, und wenn dieser Buffer voll ist, keine weiteren send()s der Server zugelassen werden?



  • also dein os hat ein-/ausgans-fifo-caches für quasi alle io-operationen. wie groß der ist, ist systemabhängig und dein system regelt bei synchronen zugriffen auch, dass der nicht überlaufen kann, in dem er bspw bei netzwerkclients die empfangsbestätigung verweigert oder aktiv mitteilt, dass es zu schnell geht.
    bei async liegt je nach system ein teil der verantwortng bei dir.



  • @vp:
    Der Sender-PC puffert es solange bis er vom Empfänger-PC die Bestätigung bekommen hat dass dieser es nun empfangen & gepuffert hat. Der Empfänger-PC puffert es dann solange bis das Empfänger-Programm es abholt.
    Wenn das Empfänger-Programm sich zu lange Zeit lässt, oder der Sender-PC zu schnell Daten schickt, dann kann es sein dass die max. Grösse des Empfangspuffers beim Empfänger-PC erreicht wird.
    Macht aber nix, weil der Empfänger-PC dem Sender-PC auch ständig mitteilt wie viel von seinem Puffer noch frei ist. Der Sender-PC hört dann, wenn laut seinen Informationen im Empfänger-Puffer nichtmehr genug Platz ist, automatisch auf neue Daten zu schicken bis er wieder vom Empfänger-PC gehört hat dass wieder Platz in dessen Puffer frei ist.



  • Danke hustbaer, das hilft mir!

    hustbaer schrieb:

    Macht aber nix, weil der Empfänger-PC dem Sender-PC auch ständig mitteilt wie viel von seinem Puffer noch frei ist. Der Sender-PC hört dann, wenn laut seinen Informationen im Empfänger-Puffer nichtmehr genug Platz ist, automatisch auf neue Daten zu schicken bis er wieder vom Empfänger-PC gehört hat dass wieder Platz in dessen Puffer frei ist.

    Gilt das auch bei UDP? Und wie lange macht der Sender PC das mit?



  • Vielleicht wäre es angebracht, wenn du dich mal intensiver mit der TCP/IP Protokollfamilie auseinandersetzt um ein besseres Verständnis dafür zu bekommen 🙂

    Was sind diese half-open Connections?



  • @vp:
    Nein, für UDP gilt das nicht.

    Bei UDP schickst du einfach Pakete, und ob ein Paket durchgeht oder nicht ist einfach "Glückssache". Es sind da zwar AFAIK einige Mechanismen am Werk die versuchen den Verlust zu minimieren, wie die genau funktionieren weiss ich allerdings leider nicht. Allerdings wird bei UDP niemals eine Re-Transmission von bereits gesendeten Paketen gemacht. Der Sender-PC muss also schonmal garnix puffern nachdem er es abgeschickt hat. Der Empfänger PC puffert die Pakete soweit ich weiss eine gewisse Zeitlang bzw. bis der Puffer den er hat eben "voll" ist, weitere Pakete werden dann einfach verworfen wenn das Empfänger-Programm die Daten zu langsam abholt.



  • @Bücherwurm
    Eine halb offene Verbindung ist die wo das Telefon noch läutet. D.h. der eine hat ruft grad an, der andere hat aber noch nicht abgehoben.
    Diese Phase ist normalerweise recht kurz, daher wirkt sich das Limit von max. 10 halboffenen Verbindungen bei Windows XP auch nicht so tragisch aus.
    Wenn der "angerufene" PC allerdings gerade nicht da ist (z.B. nicht läuft oder die Internet-Leitung nen Hänger hat), dann dauert diese Phase ziemlich lange (etliche Sekunden), und endet dann mit einem Fehler.

    Da solche Fälle (der angerufene PC meldet sich nicht) bei bestimmten Programmen ziemlich oft auftreten werden diese auch stark ausgebremst. z.B. Viren die einfach irgendwelche zufälligen IPs berechnen und versuchen sich dorthin zu connecten, oder auch P2P Programme die versuchen Peers zu connecten die aber grad nicht online sind.


Anmelden zum Antworten