Frage zu Threads
-
Hallo,
ich schreibe gerade einen Sortieralgorithmus (zur Übung).
Dieser befidet sich nun in einer Klasse und dort in einer Methode die Static ist
(Ich finde es macht anders keinen Sinn).Also etwa so:
template<class T_Zielklasse> class sortieren { public: static void Sort(T_Zielklasse *feld,long laenge) { ... ... ... } };Nun möchte ich in diesem Algorithmus etwas parallel ausführen.
Ich kenne mich mit threads nicht besonders aus und wollte es so machen:private: static DWORD WINAPI ThreadFunc (LPVOID data) { ...... ..... }Nun die Frage, wenn ich mit Threads Arbeite, wie kann ich den Zeiger auf das
Array in den Thread bekommen?
-
template<class T_Zielklasse> class sortiere{ struct Job{ T_Zielklasse* start; int len; Job(T_Zielklasse* _start,int _len) :start(_start),len(_len){ } }; void Sort(T_Zielklasse *feld,long laenge) { if(laenge>1000000){ BeginThread(...,new Job(feld,laenge/2)); BeginThread(...,new Job(feld+laenge/2,laenge-laenge/2)); WarteAufDieBeidenTreads(...); } else{ ... } } private: static DWORD WINAPI ThreadFunc (LPVOID data) { }
-
volkard schrieb:
BeginThread(...,new Job(feld,laenge/2)); BeginThread(...,new Job(feld+laenge/2,laenge-laenge/2)); WarteAufDieBeidenTreads(...);Wenn Du direkt nach dem Starten eines Threads darauf wartest, dass er beendet wird, dann kommt das einem Funktionsaufruf der Threadfunktion gleich, da ja dann synchron statt asynchron gearbeitet wird.
Man schreibt die Sortierfunktion so, dass sie, wenn sie einen Thread erzeugt, ihn in eine Liste oder sowas einklinkt, die dann spaeter zum Warten verwendet wird. Das Warten kann man am Ende der Sortierung machen (also um auf alle Threads zu warten). Das geht z.B. sehr gut mit Events, die am Ende des jeweiligen Sortierparts ausgeloest werden. Man raeumt dann die Threads zu einem spaeteren Zeitpunkt ab.
Zum Warten auf mehrere Threads kann man z.B. WaitForMultipleObjects() oder MsgWaitForMultipleObjects() verwenden (letztere blockiert die Message Queue des Applikationsfensters nicht). Danach schliesst man alle Thread-Handles.
Richtig ist jedoch, die Aufsplittung in Threads nur dann zu machen, wenn es wirklich notwendig ist. Denn Overhead beim Erzeugen von Threads sollte man nicht vernachlaessigen.
Im Prinzip ist es bei vorliegendem Fall besser, einen extra Sortier-Thread zu machen, der z.B. beim Oeffnen des Hauptfensters schon gestartet wird, und der seine Auftraege aus einer Job-Queue bekommt (ein Job enthielt dann nur die Parameter fuer die Sortierfunktion). Er sortiert dann im Hintergrund die Daten und benachrichtigt dann z.B. das Hauptfenster. Man darf natuerlich die Synchronisation ueber Mutex-Semaphoren nicht vergessen. D.h. der Speicher, der gerade sortiert wird, muss abgesichert werden.
-
Hallo,
leider habe ich das mit der Variablenübergabe nicht ganz hinbekommen / verstanden.
Also in etwa so:
int main (void) { int laenge=7; int *p = new int [laenge]; for (int i = 0; i < 10; i++) { p[i]=i; } //p und laenge an einen Thread übergeben, ohne dass p oder laenge eine globale Variable sind und im Thread einfach //die werte von p[0] bis p[laenge-1] ausgeben return 1; }Könnte Jemand BITTE ein kurzes Beispiel schreiben, dass sich ganz kompilieren lässt?
MfG
Andreas
-
Du müsstest dir wohl ein Struct oder eine Klasse basteln und dort dann auch laenge mit drin speichern. Dann übergibst du einen Zeiger darauf an den Thread.
Oder du fügst einfach noch ein Element mit einem bestimmten Wert (z.B. 0 oder irgendeine Konstante) an und hörst dann auch, sobald du dieses erreichst.
-
Hallo,
danke soweit! Ich habe jetzt die Klasse gebaut so , wie "flenders" es vorgeschlagen hat:
class Informationen { private: long laenge; int *array; public: Informationen(int l, int *a):laenge(l), array(a) {} int getlaenge() { return laenge; } int* gerarray() { return array; } }; int main (void) { int laenge=7; int *p = new int [laenge]; for (int i = 0; i < 10; i++) { p[i]=i; } Informationen *Inf = new Informationen(laenge,p); //p und laenge an einen Thread übergeben, ohne dass p oder laenge eine globale Variable sind und im Thread einfach //die werte von p[0] bis p[laenge-1] ausgeben return 1; }Dann übergibst du einen Zeiger darauf an den Thread.
Genau das ist ja mein Problem: Wie geht es jetzt weiter?
-
Ich weiß nicht, wie du jetzt deine Thread erzeugst, aber bei _beginthread(ex) hast du ja genau dafür das den Parameter arglist
