Thread Exit Handler ohne DLL?
-
Gibt es eine Möglichkeit Thread Exit Handler (bzw. auch Thread Start Handler) zu verwenden ohne eine DLL deren DllMain man dafür verwendet?
Konkret geht es um einige init bzw. cleanup Funktionen die in einer Lib gebraucht werden, und die eben pro Thread ausgeführt werden müssen. Und diese Lib sollte eben wenn möglich auch rein statisch linkbar sein -- also ohne irgendeine eigene DLL auskommen. Die Verwendung von standard System DLLs wäre natürlich kein Problem.
Ich vermute zwar dass es nicht geht, aber da hier ein paar Leute sind die von WinAPI doch mehr Ahnung haben als ich dachte ich mir ich frage mal nach

-
Da hilft Dir nicht mal eine DLL... das Thread-Detach wird bei einer DLL *nur* aufgerufen, wenn der Thread korrekt beendet wird.
Es wird also weder bei ExitProcess/TerminateProcess noch bei TerminateThread oder einer Exception im Thread aufgerufen.
IMHO gibt es nur diese unzuverlässige Methode mit DllMain...
Das zuverlässigste ist immer noch eine Funktion zur Verfügung zu stellen, welche der "Anwender" vor dem Ende aufrufen muss.
-
Naja... TerminateThread, ExitProcess etc. - das ist mir eigentlich alles egal, das sind IMHO sowieso Extremfälle. Von daher wäre die DllMain Methode schon ok.
Und eine cleanup Funktion möchte ich unter allen Umständen vermeiden. Stell dir mal vor jmd. will z.B. eine logging Library schreiben, und diese wiederum verwendet ne thread-local-data Klasse aus einer Threading Library welche den Aufruf einer Cleanup Funktion verlangt. Das ist nicht schön, dann muss jeder der irgendwo ein Log ausgeben will die Cleanup Funktion verwenden. Noch schlimmer wirds sobald man irgendwo Callbacks hat -- wenn ich in dem Callback drinnen dann diese Logging Library verwenden möchte... ich habe ja dann oft keine Kontrolle darüber wie der Thread beendet wird.
IMHO ist das eine Sache die die Runtime zur Verfügung stellen sollte, so wie es ja auch onexit() gibt. Bloss eben leider kein onthreadexit()

Und da es die Runtime (MSVC) leider nicht kann ... werde ich wohl eben auf die "DllMain Lösung" zurückgreifen müssen.
-
Auf API Level kenne ich dazu nichts. Die Thread Implementierung der MFC sieht Thread-Local-Storage vor, der auch korrekt bei Ende eines Threads freigegeben wird. Das können auch komplexere Objekte sein.
Was spricht dagegen, eine komplette eigene C++ Wrapper Klasse zu bauen, die genau das für Dich organsisiert?
-
Martin Richter schrieb:
Auf API Level kenne ich dazu nichts. Die Thread Implementierung der MFC sieht Thread-Local-Storage vor, der auch korrekt bei Ende eines Threads freigegeben wird. Das können auch komplexere Objekte sein.
Was spricht dagegen, eine komplette eigene C++ Wrapper Klasse zu bauen, die genau das für Dich organsisiert?
Nix spricht dagegen. Genau das will ich ja machen. Bloss wie mache ich das ohne "at_thread_exit()" oder DllMain? Also WIE soll ich das implementieren? Stehe da leicht an...

Ich werd' aber auf jeden Fall mal in die MFC reingucken, bloss glaube ich dass die den gleichen Kompromiss eingeht wie alle anderen TLS Implementierungen die ich bis jetzt kenne, nämlich vom User zu verlangen dass er vor Ende des Threads seine TLS Objekte selbst wegputzt. Was IMHO unvertretbar ist.
EDIT: BTW: falls du das so meintest... eine eigene "Thread" Klasse zu bauen ist eine "Lösung" die sich für mich auch verbietet - wenn dann muss das mit detached Threads bzw. einfach Threads die NICHT von meiner Lib gestartet wurden genauso laufen. Warum siehe weiter oben: das soll z.B. auch in Callback Funktionen einsetzbar sein die von Threads aufgerufen werden die ausserhalb meiner Kontrolle entstanden sind.
-
Das freigeben von MFC/CRT Ressourcen, welche in einer externen DLL allokiert wurden, geschieht *nur* über den DllMain Mechanismus...
Aus diesem Grunde gibt es auch meinen schönen KB-Artikel:
Do not call "DisableThreadLibraryCalls" in a DLL which is statically linked to the CRT
http://support.microsoft.com/kb/555563/en-usWeclhes das Problem schildert und auch etwas erklärt...
Fazit: Es wird nichts um das DllMain drum rum kommen, wenn Du nicht kontrolle über das Erzeugen des threads hast!
Wenn Du natürlich das Thread-Erzeugen kontrollieren kannst, dann kannst Du ja Deine eigene ThreadMain angeben und hast das "Ende" unter Kontrolle. Aber Dir ging es ja gerade um "fremde" Threads, oder?