Hi, ich erzeuge mein Thread in WinAPI und VC so: hThread = CreateThread( NULL, 0, ThreadFunc, &dwThrdParam, 0, &dwThreadId);identifier SetThreadPriority(hThread, THREAD_PRIORITY_NORMAL); und beende es so: void TermThread() { GetExitCodeThread(hThread, lpExitCode); ExitThread(*lpExitCode); // Diese Zeile verursacht Fehler CloseHandle(hThread); } Wie schon in der Zeile kommentiert, verursacht diese Zeile einen Fehler - siehe Anhang! Dass der Thread erzeugt wir, weiss ich da die Routine funktioniert aber warum lässt sich der Thread nicht schliessen? Was muss man da beachten, eigentlich ist das nichts wildes.
Ist denn lpExitCode möglicherweise NULL? Wer ruft Deine Funktion TermThread auf? Die Threadroutine oder etwa der Hauptthread? (Der darf das nicht und würde sich selbst damit terminieren)
hmm könntest du mal deine threadfunc posten ??? dir ist schon klar,dass exitthread aus dem thread der beendet werden soll aufgerufen wird oder??? btw TerminateThread hat etwas ganz lustiges in der doku stehn.... (TerminateThread is a dangerous function that should only be used in the most extreme cases. ) also das ist eine subtil bösartige funktion ;) und dann wäre noch das.. GetExitCodeThread(hThread, lpExitCode); ExitThread(*lpExitCode); // Diese Zeile verursacht Fehler hier müsste lpExitCode mit einem DWORD *lpExitCode=new DWORD oder ähnlichen initialisiert werden... und dann muss noch mit delete der speicher wieder freigegeben werden... ich finde da sowas irgendwie praktischer... DWORD dwExitCode; GetExitCodeThread(hThread, &dwExitCode); ExitThread(dwExitCode); ich schätze die access-violation kommt vom dereferenzieren vom pointer lpExitCode der aber nicht richtig initialisiert ist... 73 de oe6jwf / hans
Das sit meine Threadfunktion: DWORD WINAPI ThreadFunc( LPVOID *lpParam ) { while(TRUE) { USARTRec(); Sleep(1); } return 0; } dir ist schon klar,dass exitthread aus dem thread der beendet werden soll aufgerufen wird oder??? Nein, das war mir nicht klar. Es geht nur darum, dass wenn nichts empfangen wird, der Thread geschlossen werden kann und das wir an eine anderen Stelle überprüft.
Das Terminieren des Threads lässt sich so realisieren: Statt in der Threadfunktion ein Sleep(1) aufzurufen, wird mit WaitForSingleObject() auf ein Eventhandle gewartet. if (WaitForSingleObject(hEvent, 1) == WAIT_TIMEOUT) // weitermachen else // aufhören Dieses Event wird mit CreateEvent erzeugt: hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); Das Eventhandle kann der Threadfunktion beispielsweise über den opaken Pointer lpParam übergeben werden (sofern der nicht schon anderweitig genutzt wird). Das Event kann von beliebigen Threads mit SetEvent ausgelöst werden: SetEvent(hEvent); Anzumerken ist noch, daß ein Sleep(1) nicht sehr sinnvoll ist, da die Schedulergranularität bei 10 msec liegt - es sei denn, sie ist mit timeBeginPeriod reduziert worden. Um beim Beenden des Threads sicherzugehen, daß der sich auch wirklich beendet, kann nach den Setzen des Events mit WaitForSingleObject auf das Threadhandle gewartet werden - das nämlich wird bei Beendigung des Threads signalisiert. Eine Auswertung des ThreadExit-Codes oder gar ein Aufruf von ExitThread ist so nicht erforderlich. ExitThread wird durch return aus der Threadfunktion eh' impizit aufgerufen.
... wenn man denn MFC verwendet. Dann aber würde es sich auch empfehlen, eine der Kapselungsklassen für Threads zu verwenden (CWinThread o.ä.). Sinnvoll ist es aber meiner Ansicht nach, zunächst einmal die Mechanismen des OS zu begreifen, bevor man sie mit einer Klassenbibliothek verbirgt.
CreateThread sollte man übrigens niemals benutzen, außer man ist sich allen Einschränkungen genauestens bewusst (was bei dir mit Sicherheit nicht der Fall ist). Nimm z.B. die Funktion strstr, die einen statischen Puffer besitzt. Von CreateThread bekommt strstr nichts mit. Also haben beide Threads denselben Puffer, wodurch schnell extrem schwer zu findende Fehler entstehen (die fieserweise im Debugger gar nicht auftauchen). Schau in die Doku deines Compilers. Die Lib des Compilers bietet garantiert eine Funktion _beginthread, _beginthreadex, beginthread o.ä. an. Nur diese Funktion ist geeignet, in C einen Thread zu erstellen; denn nur mit dieser Funktion bekommt die C-Standard-Lib etwas mit von der Threaderstellung und kann statische Variablen für den neuen Thread initialisieren. CreateThread ist böse. Die Threadfunktion sollte außerdem einfach "auslaufen", d.h. mit return aufhören. Denn nur dann hat die C-Standard-Lib eine Chance, den für den Thread reservierten Speicher wieder freizugeben. ExitThread, TerminateThread etc. sind verboten.
In der MSDN Library :http://msdn.microsoft.com/library/deu/default.asp?url=/library/DEU/ vccore/html/_core_C_Run.2d.Time_Library_Functions_for_Thread_Control.asp steht aber, dass CreateThread für Win32 API gedacht ist?
_beginthread ruft intern natürlich auch CreateThread auf. Nur vorher wird halt noch die C-Standard-Lib für den neuen Thread initialisiert. CreateThread funktioniert zwar, du darfst dann allerdings die Funktionen der C-Standard-Bibliothek nicht benutzen; genau diese Warnung steht auch auf der von dir verlinkten Seite. p.s.: Solche langen URLs bitte über tinyurl.com posten, damit sie nicht umgebrochen werden.
Kann man unter MS-Windows denn keine Posix-Threads nehmen? Das CreateThread ist doch kein bischen portabel und vielleicht gibt's das beim nächsten MS-Windows nicht mehr, während pthread_create sicherlich auch in 100 Jahren noch unter so ziemlich jedem Posix-konformen Betriebssystem funktionieren wird.
Früher gab es standardmäßig eine Posix-kompatible Umgebung für Windows (als paralleles Subsystem), die aber ist wohl aufgrund von Nichtbeachtung seitens der Anwendungsprogrammierer gestorben. Von MS gibt es allerdings ein größeres Paket, das sich wohl "UNIX Services for Windows" oder so ähnlich nennt, das POSIX-Kompatibilität und einiges weiteres nachrüstet. CreateThread selbst ist ausgesprochen langzeitstabil - an der Funktion und ihrem Gebrauch hat sich seit Herbst 1992 nichts wesentliches geändert. Damals gab's die erste verfügbare Beta-Version von NT 3.1, und mit der habe ich zu der Zeit bereits gearbeitet. Wesentlich hat sich eigentlich nur die Dokumentation geändert - die ist seitdem viel besser geworden. Musste man damals bei den meisten Parametern oder auch kompletten Systemfunktionen raten, wofür sie da sein mögen, sind mittlerweile auch recht kleine Details dokumentiert. Posix-Threads begegnete ich etwas später erstmalig unter Lynx-OS, einem unixoiden Echtzeitbetriebssystem. Die frühen Linux-Varianten der Zeit unterstützten meines Wissens nach noch keine Posix-Threads; ich will allerdings nicht ausschließen, daß ich mich da irre.
Das mit der posix-kompatiblen Umgebung für Windows ist aber mehr ein Gerücht als Realität, denn zu Posix gehört nach Tanenbaum beispielsweise Fork und eine Shell, die ls versteht. Nur weil Microsoft ein, zwei Posix-Funktionen gemacht hat, ist das noch längst keine Posix-Umgebung.
"...und eine Shell, die ls versteht." man windows kann von natur aus schon ls und andere befehle aus der unix/linux welt
> Kann man unter MS-Windows denn keine Posix-Threads nehmen? sowas fragt man am besten google: http://www.google.ch/search?hl=de&q=pthread+win32&meta= und dann kommt zum beispiel das dabei raus: http://sources.redhat.com/pthreads-win32/ hab das jetzt nicht näher angeschaut...ich brauch ja keine pthreads :D
Hi @Tobi Hast du WinAVR installiert? AFAIK kann ein naturnahes Windows kein ls in der Befehlszeile. WinAVR rüstet diese Tools nach. Aber eigentlich will man sowieso eine Cygwin-Umgebung auf einem ordentlichen Windows haben. Eine Bash ist IMHO unverzichtbar. Matthias
Ja, das sehe ich auch so, denn a) gibt es unter MS-Win nur Posix-ähnliche Befehle wie dir statt ls und b) entsprechen die den Posix-Befehlen nur ein bischen. Ansonsten würden Shell-Skripte auch unter MS-Win funktionieren und man bräuchte kein cygwin. Weil Microsoft ständing die Programmierschnittstellen ändert, so dass beispielsweise meine alten Turbo-Pascal-Programme nicht mehr laufen (selbst wenn der runtime division by zero bug beseitigt ist), achte ich auf Portabilität und verwende mölichst nur Standard-Sachen, also ANSI/ISO-C, Posix usw..
"Weil Microsoft ständing die Programmierschnittstellen ändert" - was exakt magst Du da jetzt meinen? Die Einführung der Win32-API vor bald zwölf Jahren? Das damit eingeleitete Ende von DOS? Posix-Konformität muss mitnichten die Shell einschließen. Die Posix-Konformität besteht aus einer Reihe von Punkten, die beispielsweise hier http://www.microsoft.com/resources/documentation/windowsnt/4/workstation/reskit/en-us/poscomp.mspx beschreiben sind. Das NT*-eigene Posix-Subystem enspricht Posix.1 Mittlerweile wird dieses Posix-Subsystem durch ein Produkt namens Interix bzw. "Windows Services for Unix" ersetzt, das man sich wohl kostenfrei herunterladen kann http://www.microsoft.com/windows/sfu/default.asp *) NT schließt auch Windows 2000, XP und Windows 2003 ein, allerdings fehlt das Posix-Subsystem bei Windows XP
Noch was: Hier wird die Unterstützung von PThreads beschrieben http://www.microsoft.com/technet/interopmigration/unix/sfu/pthreads0.mspx
@ Rufus T. Firefly: Unter Posix verstehen Informatiker eine Umgebung, wie sie z. B. Tanenbaum im Buch "Moderne Betriebssysteme beschreibt"; dazu gehört neben Fork und Pthreads auch eine Shell, die ls versteht. Schließlich gibt's viele einzelne Posix-Standards. Und da dem MS-WinXP das Posix-Subsystem fehlt, ist es sehr weit weg von Posix.
"Unter Posix verstehen Informatiker ..." Siehst Du hier irgendwo Informatiker?
@Rufus T. Firefly Ja, wenn ich in den Spiegel schaue dann "sehe" ich einen... grins zum Thema: mal egal ob man XP als POSIX-Kompatibel oder nicht bezeichnet in der heutigen Zeit ist es vielleicht besser sich zu überlegen was man machen will, anstatt einem (alten) "Standart" hinterherzuhinken. zum anderen nützt es nix wenn mann dann zwar "unix"/Posix kompatibel programmieren/zugreifen kann, die zugrundeliegende API (Windoof) per se schon unsicher ist - oder glaubt hier irgendjemand das XP "sicher" ist ? Gruss
Ich mag diese relgiös-fundamentalistischen Diskussionen nicht. Die eigentliche Frage, wie man Threads unter Windows erzeugt, wurde geklärt, auf potentielle Probleme wurde hingewiesen und Alternativen wurden auch erwähnt. Hier jetzt das übliche Geseiere "unix/linux ist vieeel besser" bzw. "XP ist aber cooler" abzulassen ist nicht förderlich. Was ist ein "Standart"? Ich kenne nur Standart: aufrecht, leicht vornübergebeugt, lässig ... Stehen ist statisch und nicht mit Hinken in Einklang zu bringen. Alternativen zum Gebrauch der Win32-Thread-Funktionen: - PThreads (mit SFU3.5) - Threadwrapper einer Klassenbibliothek (MFC, wxWidgets, Qt) - Auf Threads verzichten, um sich persönlich nicht zu überfordern
> Auf Threads verzichten, um sich persönlich nicht zu überfordern
richtig. es geht häufig auch ohne, mit weniger kopfzerbrechen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.