Fehlermeld 12 bei "_beginthreadex()"



  • Hallo zusammen,

    ich habe eine Frage zum Windows-Fehlercode 12.
    Dieser Fehlercode wird von der Funktion "_beginthreadex()" geliefert und bedeutet, wenn man der Beschreibung glauben darf, dass kein "Systemspeicher" mehr vorhanden ist.

    Hintergrund:

    Es geht um eine komplexere Serveranwendung (unter Windows Server 2003 bzw XP), die Benutzeranfragen über IP entgegennimmt und in separaten Threads bearbeitet. D.h. es werden ständig Threads gestartet und beendet. Das ganze läuft i.A. stabil ohne Probleme.

    Nun tritt ab und zu beim Starten eines Threads besagter Fehlercode 12 auf, dann muss die Anwendung beendet und neu gestartet werden. OK, es könnte ja sein, dass es noch irgendwo ein Memory-leak gibt, dann wäre eine solche Meldung nach etlichen Stunden oder Tagen Laufzeit durchaus denkbar. Die Meldung tritt aber auch manchmal kurz nach dem Start der Anwendung auf.

    Mir ist nicht mal ganz klar, um welche "Sorte" Speicher es geht, vielleicht um irgendeinen Systempool?

    Mit Absicht bekomme ich den Fehler nur reproduziert wenn ich in einem Programm einen Thread nach dem anderen starte, wenn dann ca. 2030 Threads laufen kann kein weiterer mehr gestartet werden und der Fehlercode 12 wird geliefert. Diese Situation tritt in unserer Anwendung aber garantiert nicht auf.

    Hat jemand irgendwelche Erfahrungen damit oder Ideen ?

    Wäre für Hinweise echt dankbar

    mfg Thoams



  • Dieser Thread wurde von Moderator/in Shade Of Mine aus dem Forum ANSI C in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Es geht mit an Sicherheit grenzender Wahrscheinlichkeit um Adressraum und nicht um Speicher.
    Ein Programm unter Windows hat bloss 2GB Usermode Adressraum, und jeder Thread frisst standardmässig 1MB davon (für den Stack). Speicher wird dabei viel weniger verbraucht, es wird bloss der Adressraum reserviert.

    Was wahrscheinlich passiert: die Threads werden nicht sauber beendet, und der Stack wird deswegen nicht freigegeben. Nach ~2000 Threads ist also Sense, auch wenn diese Threads nichtmehr "laufen" und u.U. sogar vom Task-Manager nichtmehr angezeigt werden.

    Wir hatten das Problem mal mit einem mülligen ADODB (oder war's ODBC?) Treiber für SQL Server, der hat pro Connection ein Stackframe stehengelassen, nach ~2000 Connections war also auch Schluss und vorbei. (Ist aber mit Win 2003 Server kein Problem, die Treiber die da dabei sind funktionieren wie sie sollten.)

    Was mir gerade noch schnell einfällt zu dem Thema: TerminateTread ist BÖSE und mache BÖSE Sachen. grep mal über den gesamten Sourcecode nach TerminateTread, wenn du was findest hast du vermutlich dein Problem gefunden 🙂



  • Hi,
    danke fuer die Info.

    Dass die Threads einen eigenen Stack benutzen war mir schon klar und man kann ja bei "_beginthreadex()" auch eine gewünschte Größe angeben.
    Wenn man da allerdings weniger als 1 MB angibt ist es genau wie du sagst, dannn reserviert er 1 MB und nach ~2000 ist sense.
    Gibt man mehr als 1 MB an ist fueher Schluss.
    Hat man vorher entsprechend viel Speicher fuer andere Zwecke allokiert, dann ist auch früher Schluss.

    In unserer Anwendung werden die Threads m.E. korrekt beendet, denn es werder meist bis zu 40000 Threads gestartet und beendet (nacheinander natüerlich).
    Vielleicht gibts aber noch ein anderes Memory-Leck und mit der Zeit steigt der Speicherverbrauch an, so dass dan irgendwann auch keine Threads mehr gestartet wreden können.
    Das wurde zwar auch alles schon gecheckt, aber ich werde mal in dieser Richtung weitersuchen



  • Nö, wenn man weniger als 1MB angibt wird auch weniger als 1MB reserviert soweit ich weiss.
    Aber egal.
    War nur so ne Intuition das mit den Threads, weil ich das Problem eben schonmal hatte... vielleicht liegts bei dir ja wirklich an ganz was anderem.

    Nach TerminateThread würde ich aber trotzdem mal suchen, falls das noch nicht gemacht wurde. Ich meinte auch nicht dass die Threads *immer* falsch beendet werden, dann wäre fix nach 2000 Connections schluss, sondern dass in gewissen Fällen was passiert dass der Thread hängenbleibt.

    Natürlich kann es auch ein ganz normales Memory Leak sein. Wenn du Zugang zu soetwas wie Bounds Checker hast kannst du ja vielleicht den Server auf einer Debug-Maschine laufen lassen, ein paar Connections durchlaufen lassen, und sehen ob du so irgendwas findest.

    Als wir damals das Problem hatten hab' ich als ersten Schritt eingebaut dwAvailVirtual von GlobalMemoryStatus rauszuloggen. Vielleicht hilft dir das auch weiter, wenn du z.B. siehst dass nach einem bestimmten Anfragetyp immer Speicher verloren geht oder sowas.


Anmelden zum Antworten