Twitter und Facebook-Anbindung
X
Tweet Follow @twitterapi
!!! Anbindung an twitter und facebook öffnen !!!

Wenn Ihnen mein Online-Buch gefällt,
dann bedanken Sie sich doch mit einer kleinen Spende...

28.3 Threads mit Hilfe einer Templateklasse

28.3 Threads mit Hilfe einer Templateklasse

In dieser Variante habe ich einen anderen Ansatz gewählt. Ich habe aus der zu Grunde liegenden eigenen Threadklasse ein Template gebaut. Dies hat zur Folge, dass ich keine eigene abgeleitete Klasse bauen muss, hab aber somit wieder den Nachteil, dass ich die auszuführende Funktion des Threads, mit in die "main" packen muss und auch die Syntax ist nicht mehr ganz so elegant. Jedoch ist dieses Beispiel dahingehend flexibler, wenn man ähnliche Threads bauen will, welche sich beispielsweise nur durch ihre Funktion und nicht ihren Variablen unterscheiden. Zudem benötige ich keine Vererbung und somit keine virtuellen Methoden mehr.

Das eingebundene Template finden Sie wieder im Anhand. Schauen wir uns nun an, wie man es benutzt.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
					
#include <stdio.h>
#include "ThreadWrapper.h"

// Struktur, welche durch den Thread verwendet wird
struct SMyThreadData {
	int iStart;
	int iEnd;
	int iID;
};



// Durch den Thread auszuführende Funktion ////////////////////////////////////
DWORD MySimpleThreadFunc(SMyThreadData& sData) {
	for (int iCount = sData.iStart; iCount < sData.iEnd; iCount++) {
		printf("Thread: %i - %i\n", sData.iID, iCount);
		Sleep(10);
	} // end of for

	return 0;
} // MySimpleThreadFunc ///////////////////////////////////////////////////////



// Durch den Thread auszuführende Funktion ////////////////////////////////////
DWORD MyExtendedThreadFunc(CThreadWrapper<SMyThreadData>* pThread) {
	for (int iCount = pThread->m_tData.iStart; iCount < pThread->m_tData.iEnd && !pThread->IsTerminated(); iCount++) {
		printf("Thread: %i - %i\n", pThread->m_tData.iID, iCount);
		Sleep(10);
	} // end of for

	return 0;
} // MyExtendedThreadFunc /////////////////////////////////////////////////////



// Hauptfunktion der Anwendung ////////////////////////////////////////////////
int main(int argc, char** argv) {
	SMyThreadData			sData1		= {0, 10, 1};
	SMyThreadData			sData2		= {1000, 1010, 2};

	CThreadWrapper<SMyThreadData>*	pThread1	= new CThreadWrapper<SMyThreadData>(&MySimpleThreadFunc, sData1);
	CThreadWrapper<SMyThreadData>*	pThread2	= new CThreadWrapper<SMyThreadData>(&MyExtendedThreadFunc, sData2);

	printf("START\n");

	pThread1->Resume();
	pThread2->Resume();

	// Warten, bis alle Threads fertig sind
	while (!pThread1->IsFinished() || !pThread2->IsFinished()) Sleep(1);

	delete pThread1;
	delete pThread2;
	
	printf("ENDE\n");

	return 0;
} // main /////////////////////////////////////////////////////////////////////
					

Zuerst, in Zeile 5 bis 9, brauche ich wieder eine Struktur, in welche ich die Daten packe, welche der Threadfunktion zur Verfügung gestellt werden sollen. Allerdings benötige ich jetzt keinen extra Pointertyp.

Anschließend, in Zeile 14 bis 21, folgt die erste Art der Threadfunktion. Sie ähnelt jetzt wieder der Schnittstelle, wie sie in Variante eins definiert wurde, nur dass das Schlüsselwort "WINAPI" nicht enthalten ist und ich jetzt nicht mehr einen "void" Zeiger übergebe, sondern die selbst definierte Struktur an sich. Alternativ könnte man hier auch ein Objekt definieren anstelle der Struktur und könnte das Objekt übergeben. Zu beachten ist, dass man innerhalb der Threadfunktion keinen Zugriff auf das Threadobjekt hat.

In den Zeilen 26 bis 33 sehen Sie jetzt die zweite Art der Funktion, die vom zweiten Thread benutzt werden soll. Der Funktionskopf sieht jetzt ein wenig anders aus, weil ich auf diesen Weg den Zugriff auf das Threadobjekt ermöglichen will. Bei dem Parametername ist zu beachten, dass man den selbst definierten Strukturtyp als Templateparameter mit angibt. Auch hier wäre es denkbar, einen Zeiger auf ein Objekt bzw. ein Objekt selbst zu übergeben. In der Zeile 26 sehen Sie jetzt, dass ich über die Threadvariable an die entsprechende Struktur herankomme und zudem noch alle anderen Funktionalitäten des Objektes nutzen kann. Somit ist es möglich, ein Beendigungswunsch entgegen zunehmen, sprich, auf den Aufruf von "SoftTerminate" zu reagieren. Dies erkaufe ich mir allerdings durch eine etwas komplexere Syntax.

Im letzten Abschnitt, zwischen den Zeilen 39 bis 58, sehen Sie wieder die "main" Funktion, in welcher ich die Threadobjekte erzeuge, starte und anschließend wieder beende. Bis auf die Tatsache, dass ich zu Beginn erst die notwendigen Strukturen erzeuge und die Erzeugung der Threadobjekte jetzt ein wenig anders aussehen, hat sich nichts geändert.

Zum Seitenanfang
Zum Inhaltsverzeichnis

© Copyright by Thomas Weiß, 2009 - 2012