Bei der Durchführung eines Stresstests für einige Servercodes, die ich geschrieben habe, habe ich festgestellt, dass, obwohl ich close () auf dem Deskriptor handle (und das Ergebnis auf Fehler) verweise, dass der Deskriptor nicht freigegeben wird, was schließlich accept () verursacht. um einen Fehler "Too many open files" zurückzugeben.
Jetzt verstehe ich, dass dies wegen der ulimit ist, was ich nicht verstehe, warum ich es treffe, wenn ich clos () nach jedem synchronen Akzeptieren / Lesen / Senden-Zyklus rufe?
Ich bestätige, dass die Deskriptoren tatsächlich da sind, indem ich eine Watch mit lsof starte:
%Vor%Und tatsächlich gibt es ungefähr 1000 von ihnen. Außerdem kann ich mit netstat sehen, dass es keine hängenden TCP-Zustände gibt (kein WAIT oder STOPPED oder so).
Wenn ich einfach nur eine Verbindung / send / recv vom Client mache, bemerke ich, dass der Socket in lsof aufgelistet bleibt; Das ist also nicht einmal ein Ladeproblem.
Der Server läuft auf einem Ubuntu Linux 64-Bit-Rechner.
Irgendwelche Gedanken?
Also benutze ich strace (danke Gearoid), von dem ich keine Ahnung habe, wie ich jemals ohne gelebt habe. Ich habe bemerkt, dass ich die Deskriptoren geschlossen habe.
Jedoch. Und um der Nachwelt willen enthülle ich meinen törichten Fehler:
%Vor%Wie Sie sehen können, hat mein Konstruktor sofort einen Socket zugewiesen, und dann habe ich den Deskriptor durch den von accept zurückgegeben - was ein Leck erzeugt. Ich hatte den Accept-Code von einer eigenständigen Acceptor-Klasse in die Socket-Klasse umgestaltet, ohne dies zu ändern.
Mit strace konnte ich leicht sehen, dass Socket () jedesmal ausgeführt wurde, was zu meinem Glühbirnenmoment führte.
Danke für die Hilfe!
Sie hängen sehr wahrscheinlich an einem Befehl recv()
oder send()
. Erwägen Sie, ein Zeitlimit über setsockopt
festzulegen.
Ich bemerkte eine ähnliche Ausgabe auf lsof, als der Socket am anderen Ende geschlossen wurde, aber mein Thread hielt den Socket offen und hängte den recv()
-Befehl, der auf Daten wartete.