mikrocontroller.net

Forum: PC-Programmierung WinAPI und Threads


Autor: Thomas M. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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)

Autor: Hans (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Thomas M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Hans (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oder CEvent der mfc verwenden.. geht auch ganz fein...

73 de oe6jwf/hans

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... 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.

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Thomas M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In der MSDN Library
:http://msdn.microsoft.com/library/deu/default.asp?...
vccore/html/_core_C_Run.2d.Time_Library_Functions_for_Thread_Control.asp

steht aber, dass CreateThread für Win32 API gedacht ist?

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
_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.

Autor: nobody0 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: nobody0 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"...und eine Shell, die ls versteht."
man windows kann von natur aus schon ls und andere befehle aus der
unix/linux welt

Autor: Thomas X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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&...

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

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: nobody0 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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..

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"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/w...
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

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch was:
Hier wird die Unterstützung von PThreads beschrieben
http://www.microsoft.com/technet/interopmigration/...

Autor: nobody0 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ 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.

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Unter Posix verstehen Informatiker ..."
Siehst Du hier irgendwo Informatiker?

Autor: T.Stütz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Thomas X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Auf Threads verzichten, um sich persönlich nicht zu überfordern

richtig. es geht häufig auch ohne, mit weniger kopfzerbrechen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.