[c++] DLL - Thread korrekt beenden

ktm_frans

Grünschnabel
Hallo zusammen,

arbeite mit MS VS c++ 6.0.

Habe hier schon ne weile gesucht und auch einiges Nützliches gefunden zum Thema Thread. Aber leider noch nicht wie ich einen Thread beende der sich gerade in einem WaitForSingleObjekt(gEventHandle, INFINITI) befindet!
Besteht da überhaupt ne Möglichkeit ihn in der Phase ordentlich zu beenden?

Vielleicht noch was zu der Dll:
Mit ihr werden in dem Thread von bestimmten Hardwaren Daten gelesen und in eine .txt geschrieben. Die Funktionen werden aus einer anderen Applikation vom Anwender gesteuert.

Hoffe mir kann da jemand eine Auskunft geben

Danke schon einmal imVorraus

Gruß
Ktm_Frans
 
Hier nochmal nen paar detalierte Info´s zu dem Problem, vielleicht ist es dann einfacher zu verstehen!

Funktion in der der Thread gestartet wird:
Code:
DLLEXPORT void  StartLogging()
{
  /* Initialize the critical section -- This must be done before locking */
  InitializeCriticalSection(&cs);
  //... Mache noch dies und das
  myThreadHandle = CreateThread(NULL, 0, &myThreadFunc, NULL, CREATE_SUSPENDED,&dwThreadId);
  // thread startet erst jetzt
  // Durch die Funktion ResumeThread wird der Thread auf den der Handle hThread zeigt gestartet
  ResumeThread(myThreadHandle);
  //... Mache noch dies und das
}

Der Thread:
Code:
DWORD WINAPI myThreadFunc(LPVOID lpParameter)
{
  //... Mache noch dies und das
  SetThreadPriority(myThreadHandle, THREAD_PRIORITY_ABOVE_NORMAL);
  while (m_Stopped != true)
  {
    // WaitForSingleObject um auf Event zu warten
    WaitForSingleObject(gEventHandle, INFINITI);
    
     while (m_Stopped != true)
     {
        //... Daten lesen und verarbeiten
      }

  } 
  Sleep(10)
  return 0;
}
Funktion in der er gestoppt wird:
Code:
DLLEXPORT int StopLogging()
{
   //... Mache noch ein paar andere Sachen

   /* Enter the critical section -- other threads are locked out */
  EnterCriticalSection(&cs);

  // Abbruchbedingung Thread setzen
  m_Stopped = true;

  //TESTAUSGABE
  printf( "...Debug: Stopp Thread gesetzt... %i \n\n", m_Stopped);

  // Max 1 Min. Warten, bis Thread beendet
  int test = 6000;
  while (test)
  {
     Sleep(10);

     DWORD dwResult = WaitForSingleObject(myThreadHandle, 0);

     if (dwResult == WAIT_OBJECT_0)
      {
        // Thread hat sich beendet
        // TESTAUSGABE
        printf( "...Debug: Thread-Ende...\n\n");
        break;
       }
     test -= 1;
   }
   if (test == NULL)
    {
      // Thread konnte nicht inerhalb 1 Min. gestoppt werden
      return NOK;
     }

  // Schliessen des ThreadHandles
  CloseHandle(myThreadHandle);
			
  // Schliessen des EventHandles
  CloseHandle(gEventHandle);

  LeaveCriticalSection(&cs);

  // Release system object when all finished -- usually at the end of the cleanup code
  DeleteCriticalSection(&cs);

  // Funktionsrueckgabe
  return OK;

}

Habe jetzt das Problem, wenn ich kein Event von der Harware via (gEventHandle) bekomme, dass das der Thread im WaitForSingleObjekt steht und sich nicht ordentlich beenden laesst!
Wie also kann man ihn da raus bekommen?

Gruß
 
Du wechselst auf WaitForMultipleObjects und definierst dir ein eigenes Event für den ShutDown. WaitForMultipleObjects gibst du dann ein Array mit 2 Events, einmal das Hardware-Event, einmal dein Shutdown-Event.

Wenn deine DLL beendet wird, setzt du das Shutdown-Event und beendest den Thread sauber.
 
Hi Endurion;

funktioniert leider nicht ganz so wie es soll! :confused:

Habe mir nen zweites Event generiert und dann beide Events in ein Array gesteckt und diese dem WaitForMultipleObjects übergeben.
Das stoppen des Thread funktioniert auch einwandfrei, nur leider arbeitet er nicht mehr mit meinem Hardware Event.
Ich habe da wirklich noch nicht die Erfahrung, kannst da vielleicht mal rüber schauen?

Code:
// Globales
...
#define MAX_HANDLES 2
...
HANDLE gEventHandle;
HANDLE hShutDownThread;
HANDLE aHandles[MAX_HANDLES];
...
Die Handles erzeugen und zuweisen:
Code:
...
// Event-Ausloesung aktivieren
 gEventHandle = CreateEvent(NULL, FALSE, FALSE, NULL);

// Stopp Event fuer Thread generieren
hShutDownThread = CreateEvent(NULL, TRUE, FALSE, NULL);

aHandles[0] = gEventHandle;
	
aHandles[1] = hShutDownThread;
...
Benutzung im Thread:
Code:
...
// WaitForMultipleObjects(MAX_HANDLES, aHandles, TRUE, INFINITE);
...
Beenden des Thread:
Code:
...
EnterCriticalSection(&cs);

// Abbruchbedingung Thread setzen
m_Stopped = true;

// Stopp Event fuer Thread setzen
SetEvent(hShutDownThread);
...
// Schliessen des Stopp Handles fuer den Thread
CloseHandle(hShutDownThread);

LeaveCriticalSection(&cs);
...
 
Prüf mal sicherheitshalber, ob du für die Hardware und den Thread ein und dasselbe HANDLE verwendest (einfach als Hex-Wert ausgeben lassen).
 
Okay, das werde ich mal prüfen! Kann ich mir aber eigentlich nicht vorstellen...aber wer weiß!
Was mache ich wenn es die gleichen Handle sind?

Gruß
 
So, habe das eben mal geprüft!
Es sind definitiv nicht die gleichen Handle, alle drei verwendeten sind unterschiedlich
 
Sorry, ich hab mich nicht besonders klar ausgedrückt :)

Das Event für die Hardware und das zweite Handle für WaitForMultipleObjects müssen natürlich dasselbe sein. Sonst reagiert WaitForMultipleObjects ja nicht auf das Hardware-Event.
 
Hi Endurion,

kein Problem!
Okay, das habe ich ausprobiert! Leider ohne Erfolg, das WaitForMultipleObjects reagiert nicht auf das HardwareEvent, das ich der Hardware zugewiesen habe :-(
Habe mir das hier mal angeschaut: http://www.codeworx.org/cpp_tuts_1_5.php
und auf Handles anstelle von Threads umgebaut, somit sollte ich ja dann das gleiche Event verwenden! Aber wie gesagt ohne Erfolg
Habe mir jetzt ein bissel anders geholfen, da das heute laufen muss!
Habe wieder ein WaitForSingleObject genommen und die Wartezeit auf 1000 gesetzt, so kommt er alle 1000ms aus dem WaitForSingleObject raus und kann die Abbruchbedingung abfragen!
Keine saubere Lösung, aber auf die Schnelle die beste!

Hast Du vielleicht mal ein Beispiel das läuft, ich möchte das schon mit WaitForMultipleObjects und "INFINITE" lösen um die Rechenleistung so gering wie möglich zu halten, da ich noch mehre Threads starten muss!

Vielen Dank für Deine Unterstützung!
Gruß
Ktm_Frans
 
Zurück