Frage zu Threads
-
Hallo,
ich habe da mal eine Frage. Da recv() ja das Programm anhält bis es etwas empfängt, wollte ich diese Funktion gerne in einem seperaten Thread laufen lassen, damit das Hauptprogramm weiterlaufen kann.
Zum starten eines neuen Threads kenne ich nur die Funktionen CreateThread() und _beginthread(). Welche der Funktionen sollte ich verwenden? Oder gibt es vielleicht noch eine bessere Funktion?
Außerdem wüsste ich gerne, wie ich den erstellten Thread aus dem Hauptprogramm heraus beenden kann. Oder wird der einfach mitbeendet, wenn das Hauptprogramm beendet wird?Mit freundlichen Grüßen
DerRatlose
-
Die erste Frage hätte google dir beantworten können. Google sagt benutze _beginthread weil CreateThread Memoryleaks hat die beginthread aufräumt.
Wenn sich dein Programm beendet beenden sich auch die geöffneten Threads. Alternativ frag mal MSDN nach TerminateThread. Du musst nur etwas aufpassen weil ein gekillter Thread nicht mehr dazu kommt Speicher freizugeben.
Edit: Was du eigentlich willst ist ein Socket was nicht blockiert.
von http://support.microsoft.com/kb/181611
Wenn ein Socket erstellt wird, ist standardmäßig ein blockierenden Socket. Sie können den FIONBIO-Befehl in die Ioctlsocket API-Aufruf, WSAEventSelect oder WSAAysncSelect verwenden, um den Socket Modus Blockieren ändern zu nicht blockierend. Wenn ein Winsock-Aufruf nicht sofort durchführen können, der Aufruf fehl, und WSAGetLastError gibt einen Fehler WSAEWOULDBLOCK zurück, wenn Sie einen nicht blockierenden Socket oder Aufruf Blöcke bis zum Abschluss der Operation, wenn es einen blockierenden Socket ist.Mannomann, deutsch können die aber auch nicht

-
Hi,
danke für die Antwort. Dass CreateThread Memoryleaks erzeugen kann, hatte ich zwar irgendwo gelesen, aber ich dachte ich frage trotzdem mal ganz allgemein nach meinen Möglichkeiten.
TerminateThread scheint mir keine so gute Lösung zu sein in diesem Fall.
Das mit den nichtblockierenden Sockets klingt gut. Dann könnte ich den 2. Thread abwechselnt überprüfen lassen, ob neue Daten reinkommen oder ob er sich beenden soll. Kann ja ein Sleep(5) reinsetzen, damit es die CPU nicht hochjagt, oder?
Mit freundlichen Grüßen
DerRatlose
-
Warum wurde der CreateThread-Leak nicht schon längst gepatcht?
-
DerRatlose schrieb:
Das mit den nichtblockierenden Sockets klingt gut. Dann könnte ich den 2. Thread abwechselnt überprüfen lassen, ob neue Daten reinkommen oder ob er sich beenden soll. Kann ja ein Sleep(5) reinsetzen, damit es die CPU nicht hochjagt, oder?
wenn du mehrere threads benutzt, dann nimm besser blocking sockets. dafür isses ja da (polling verbrät in multithreaded-anwendungen nur unnötig rechenzeit). wenn die verbindung geschlossen wird oder irgendein fehler passiert ist, dann kommen revc/send sowieso wieder zurück und du kannst im thread entsprechend darauf reagieren.
Nebenfrage schrieb:
Warum wurde der CreateThread-Leak nicht schon längst gepatcht?
weil's kein bug ist. das ist nur relevant, wenn die CRT benutzt wird. eine win-anwendung, die keine CRT braucht, kann CreateThread problemlos benutzen.

-
;fricky schrieb:
Nebenfrage schrieb:
Warum wurde der CreateThread-Leak nicht schon längst gepatcht?
weil's kein bug ist. das ist nur relevant, wenn die CRT benutzt wird. eine win-anwendung, die keine CRT braucht, kann CreateThread problemlos benutzen.

Und auch bei der CRT tritt das "Problem" *nur* auf, wenn Du gegen die statische CRT linkst!
-
Hier noch was zu lesen für alle Wissbegierigen: http://blog.m-ri.de/index.php/2007/11/28/createthread-und-die-crt/
-
nwp2 schrieb:
Mannomann, deutsch können die aber auch nicht

Der Artikel wurde maschinell übersetzt. Steht drüber

Danke für die vielen Hinweise. Haben mir sehr geholfen.
@ _matze: Danke für den Link. Gibt einen guten Überblick über das Problem.
Mit freundlichen Grüßen
DerRatlose
-
Jochen Kalmbach schrieb:
;fricky schrieb:
Nebenfrage schrieb:
Warum wurde der CreateThread-Leak nicht schon längst gepatcht?
weil's kein bug ist. das ist nur relevant, wenn die CRT benutzt wird. eine win-anwendung, die keine CRT braucht, kann CreateThread problemlos benutzen.

Und auch bei der CRT tritt das "Problem" *nur* auf, wenn Du gegen die statische CRT linkst!
Wobei ich auch nicht ganz einsehe, wieso es mit statischer CRT hier ein Problem geben muss. Über bestimmte Einträge im PE-Image kann man sich auch ohne DLL einen Callback besorgen, der für jeden beendeten Thread aufgerufen wird.
Wie es z.B. die Boost.Thread macht.
-
Interessant... hast Du da mehr Info darüber?
-
Jochen Kalmbach schrieb:
Interessant... hast Du da mehr Info darüber?
Eine EXE kann auch EXPORTS haben. Der folgende Code funktioniert also.
Entsprechend auch rückwärts aus einer DLL.int _tmain(int argc, _TCHAR* argv[]) { HINSTANCE hInst = GetModuleHandle(NULL); PFOO pFoo = reinterpret_cast<PFOO>(GetProcAddress(hInst,"Foo")); pFoo(); return 0; } extern "C" void __declspec(dllexport) Foo() { }Insofern hat hustbaer recht. Die DLL könnte feststellen mit welcher CRT die EXE arbeitet...
-
Hab ich jetzt nicht verstanden... das was Du sagst ist mir bekannt... aber was hat das mit "ThreadDetach und statischer CRT zu tun"?
Lt. hustbaer soll es eine Möglichkeite geben, dass man sich informieren lässt, wenn ein Thread beendet wurde... mir ist dies nicht bekannt... das wollte ich wissen...
Also, ein ganz simples Beispiel will ich sehen:
DWORD CALLBACK MyThread(LPVOID) { } VOID CALLBACK ThreadDetachCallback() { // Destroy CRT memory... } int _tmain() { // TODO: // Register for Thread-Detach (or termination) // Either via Code or via Linker-Options... HANDLE hThread = CreateThread(...); WaitForSingleObvject(hThread, INFINITE); }Und das ganze für eine *simple* EXE, welche statisch gelinkt ist... so hab ich zumindest hustbaer verstanden.... wie gesagt, ich kenne diese Möglichkeit nicht... deshalb frag ich nach...
Die Betonung lag in seinem Posting auf "ohne DLL"!
-
Jochen Kalmbach schrieb:
Die Betonung lag in seinem Posting auf "ohne DLL"!
OK! Dann war ich zu schnell und habe Deine Rückfrage falsch interpretiert.
Mich würde das auch interessieren.
-
Steht z.B. hier beschrieben:
http://www.codeproject.com/KB/threads/tls.aspx
Wenn ich das richtig verstehe, braucht man dafür keine DLL CRT.
-
Leider ist bei dem Artikel kein Code mehr dabei...
Aber jetzt fällt es mir auch wieder ein

Sowas in der Art:
#include <windows.h> #include <stdio.h> #include <tchar.h> VOID NTAPI my__dyn_tls_init( PVOID hDllHandle, DWORD dwReason, LPVOID lpreserved ) { const char *szReason = "(unknown)"; switch(dwReason) { case DLL_PROCESS_DETACH: szReason = "DLL_PROCESS_DETACH"; break; case DLL_PROCESS_ATTACH: szReason = "DLL_PROCESS_ATTACH"; break; case DLL_THREAD_ATTACH: szReason = "DLL_THREAD_ATTACH"; break; case DLL_THREAD_DETACH: szReason = "DLL_THREAD_DETACH"; break; } printf("my__dyn_tls_init (dwReason: %s) (ThreadID: %d)\n", szReason, GetCurrentThreadId()); return; } #pragma section(".CRT$XLC",long,read) // copied from "crt\sect_attribs.h" static __declspec(allocate(".CRT$XLC")) PIMAGE_TLS_CALLBACK __xl_c = my__dyn_tls_init; #pragma comment(linker, "/include:__tlregdtor") DWORD CALLBACK Test1(LPVOID) { printf("Test1-Thread\n"); return 0; } int _tmain() { printf("main started\n"); DWORD tid; HANDLE h = CreateThread(NULL, 0, &Test1, NULL, 0, &tid); WaitForSingleObject(h, INFINITE); printf("main ended\n"); }Welches bei mir Folgendes aisgibt:
main started
my__dyn_tls_init (dwReason: DLL_THREAD_ATTACH) (ThreadID: 3896)
Test1-Thread
my__dyn_tls_init (dwReason: DLL_THREAD_DETACH) (ThreadID: 3896)
main ended
my__dyn_tls_init (dwReason: DLL_PROCESS_DETACH) (ThreadID: 3496)Das das Process_attacxh und das erste Thread_attach nicht kommt, kängt wohl vom OS ab (lt. Kommentaren in der CRT)...
Da stellt sich mir allerdings wirklich die Frage, warum es die (statische) CRT nicht gleich "richtig" implementiert hat...
PS: Vermutlich weil es nur in den "meisten" Fällen geht, nicht aber in allen (z.B. wenn es eine DLL ist, welche statisch gegen die CRT gelinkt wurde und diese dann auch noch via LoadLibrary geladen wurde. Dann gehen AFAIK die TLS-Aufrufe nicht...) Wobei: Wenn es eine DLL ist, passt es ja sowieso, oder? Bin ganz verwirrt... nein passt nicht... ach was solls...