# Thread



## kerian (5. Mai 2004)

Ich habe mit einem Thread mächtig Ärger!

Es ist eine SDI Anwendung. Ich starte in mit

pThread0 = AfxBeginThread (ThrFunLesen, this); 

Funktioniert auch wunderbar. Aber das Problem ist in zu stoppen.


```
UINT CGR2Data::ThrFunLesen(LPVOID pParam) 
 { 
   g_pGR2Data->ThrLesen();
   return 0; 
}


void CGR2Data::ThrLesen() 
{ 
cs.Lock();
  while (m_Flagthr0)  
  {  
	char S1[10];
	char S2[10];
    RS232R();
	if(!g_pGR2Fifo->Empty())
	{
	  g_pGR2Fifo->Pop((PPaket)S1);
	  LonDataIn(S1);
	  PostMessage(m_msg,nDlgActionMsg,0,0);
	  if(m_bmess)PostMessage(m_msg1,nActionMsg,0,0);
	  if(!m_bmess)PostMessage(m_msg2,nActionMsg2,0,0);
	}
	if(!g_pGR2Fifow->Empty())
	{ 
	  g_pGR2Fifow->Pop((PPaket)S2);
      RS232W(S2);
	}
	//m_Flag = m_Flag;
   } 
  cs.Unlock();
}
```

Ich versuche In der Methode OnDestroy zu Stoppen!
Den er soll ja automatisch gestoppt werden. Mach ich mir ein
Button für das Stoppen dann geht das!


```
void CGR2View::OnDestroy() 
{   
 	CFormView::OnDestroy();	
	// TODO: Code für die Behandlungsroutine für Nachrichten hier einfügen
	     g_pGR2Data->m_Flagthr0 = FALSE;
    ::Sleep(0); //give control to other threads
//	TerminateThread(g_pGR2Data->pThread0,0);
    ::WaitForSingleObject(g_pGR2Data->pThread0 , INFINITE); //wait until thread has stopped	
}
```

bekomme aber immer ein Speicher leak!

```
Thread 0x8C4 wurde mit Code 0 (0x0) beendet.
Detected memory leaks!
Dumping objects ->
thrdcore.cpp(166) : {93} client block at 0x00302B10, subtype 0, 112 bytes long.
a CWinThread object at $00302B10, 112 bytes long
Object dump complete.
Thread 0x90C wurde mit Code 0 (0x0) beendet.
Das Programm "E:\Data\visual\Projekt\Gr2_0\Debug\GR2.exe" wurde mit  Code 0 (0x0) beendet.
```


----------



## kerian (6. Mai 2004)

Hallo,
ich habe in der OnDestroy Methode Sleep(200); gesetzt.
Bekomme jetzt keine weiter Fehlermaldung! Ob das OK ist?
Ich glaube das oben war einwenig verwirrend! sorry 


```
"C:\WINNT\system32\comctl32.dll" wurde geladen. Es wurden keine entsprechenden Symbolinformationen gefunden.
Warning: no message line prompt for ID 0xE001.
"C:\Programme\Yahoo!\Messenger\idle.dll" wurde geladen. Es wurden keine entsprechenden Symbolinformationen gefunden.
"C:\WINNT\system32\msvcrt.dll" wurde geladen. Es wurden keine entsprechenden Symbolinformationen gefunden.
Thread 0x430 wurde mit Code 0 (0x0) beendet.
Thread 0x474 wurde mit Code 0 (0x0) beendet.
Das Programm "E:\Data\visual\Projekt\Gr2_0\Debug\GR2.exe" wurde mit  Code 0 (0x0) beendet.
```


----------



## oglimmer (6. Mai 2004)

TerminateThread ist keine gute Funktion.



> TerminateThread is used to cause a thread to exit. When this occurs, the target thread has no chance to execute any user-mode code and its initial stack is not deallocated. DLLs attached to the thread are not notified that the thread is terminating.
> 
> TerminateThread is a dangerous function that should only be used in the most extreme cases.



Besser ist es dafür zu sorgen, dass der Thread sich selbst beenden kann. Sowas wie:


```
// Im Thread
while ( run ) {
....
}

// in OnDestroy()
myThread.run = false;
```


----------



## kerian (6. Mai 2004)

Genau das habe ich auch schon probiert!
Wenn Ich mir ein Button erstelle und halt
m_Flagthr0 = False; 
sage wird er beendet, und die Applikation kann halt dann beendet werden.
Wenn ich das ganze in die OnDestroy() einfüge und dazu noch
mit der Funktion 
::WaitForSingleObject(g_pGR2Data->pThread0 , INFINITE); 
warte bis er beendet ist
Klappt das ganze nicht.
Ich glaube er ferliert den Handel oder so?


----------



## Endurion (6. Mai 2004)

Das Handle muss auf jeden Fall mit CloseHandle zugemacht werden, ob der Thread noch lebt oder nicht. Windows verknüpft das Handle mit einem Speicherblock oder Daten, und die werden erst dann sauber freigegeben.


----------



## kerian (6. Mai 2004)

ja mh ich habe mir jetzt so geholen:

```
void CGR2View::OnDestroy() 
{   
 	CFormView::OnDestroy();	
	// TODO: Code für die Behandlungsroutine für Nachrichten hier einfügen
	TRACE("VOR THREAD");
	g_pGR2Data->m_Flagthr0 = FALSE;
    ::Sleep(0); //give control to other threads
    ::WaitForSingleObject(g_pGR2Data->m_hThread0 ,INFINITE); //wait until thread has stopped
//	CloseHandle(g_pGR2Data->m_hThread0);
//  error("WaitForSingleObject");
	TRACE("DANACH");

}
```

Ich habe zuerst mit dem Zeiger vesucht zu beenden aber das klappte nich so ganz! Da habe ich mir den Handel gerätet und halt mit Im jetzt den Thread beendet! scheint zu funktionieren!


----------

