Mehrere Threads greifen auf ein ThreadFunc zu
-
Hallo liebe Community,
ich habe das Folgende vor.1. Es gibt eine Funktion, die die eine Integer ausgibt.
Die Integer steht für die ID des Threads.Die Funktion könnte so aussehe:
bool testProg::write(int myID)
{
// Ausgabe der Integer
}2. Jetzt sollen 100 Threads parallel laufen und die ganze Zeit nur ihre ID ausgeben:
Die Threads würde ich gerne mit AfxBeginThread(...) starten.
Meine eigentlich Frage:
Bei AfxBeginThread kann ich ja einen Pointer übergeben.Meine Threadfunktion braucht 1.den this-Pointer, um testProg::write aufrufen zu können und 2.die Integer, die die ID angibt.
Ich habe mir gedacht, dass ich den this-Pointer und die int in ein struct packe und dann dieses struct übergebe.Wie geht das?
Könnte mir einer von euch nen Mini-Sample schreiben?
Ich kriege das einfach nicht hin.Liebe Grüße,
Julia
-
Na eine struct definieren un den Zeiger übergeben.
stuct data { anydataclass *p; int i; }; ... data d; d.p = this; d.I = 5; AfxBeginThread(threadFunc,&d);Aber was soll das? Das bringt nichts, denn durch die Synchronisation über das Ausgabeobject stehen alle Threads mehr oder weniger auf dem Schlauch.
Außerdem musst Du aufpassen, dass der Zeiger den Du übergibst auch noch lange genug gültig ist wenn Dein Thread weiterläuft. Evtl. solltest Du new verwenden, wenn Du weist wann Du dir struct entsorgen kannst.
-
Hallo Martin,
vielen Dank für deine Antwort.Das mit der Ausgabe ist nur ein Beispiel.
Wie meinst du das? "die Threads stehen auf dem Schlauch."Grüße,
Julia
-
Wenn Du einen Ausgabe-Kanal hast, gleich welcher Form wird die Ausgabe synchronisiert, will heißen: Immer nur einer kann schreiben. D.h. Deine ganzen Threads reihen sich mehr oderweniger hinter einander und d.h., es ist langsamer, als wenn Du nur einen Thread verwenden würdest.
-
Ich habe es jetzt mal versucht das so zu realisieren und komme nicht weiter.
(Es geht mehr um ein proof-of-concept
Hier mein Code:
struct data { LPVOID p; int i; }; UINT Ctest_appDlg::test_worker(LPVOID pParam) { data* mydata = (data*) pParam; Ctest_appDlg* pDlg = (Ctest_appDlg*) mydata->p; pDlg->test_function(mydata->i); return 1; } bool Ctest_appDlg::test_function(int id) { CString a; a.Format("\r\nmyID: %i",id); TRACE(a); return true; } bool Ctest_appDlg::run() { data test[3]; for(int i=0; i<3; i++) { test[i].i = i; test[i].p = this; ::AfxBeginThread(test_worker, &test[i]); } return true; }Ausgabe:
myID: 0Thread 0x644 wurde mit Code 1 (0x1) beendet.
myID: 1Thread 0x1668 wurde mit Code 1 (0x1) beendet.
myID: 1598900256Thread 0x16A8 wurde mit Code 1 (0x1) beendet.Ohne Array kriege ich das Gleiche.
Woran liegt das?Grüße,
Julia
-
Kann mir keiner von euch helfen?
Eigentlich ist das doch ein Standardproblem, oder?Grüße,
Julia
-
Ich glaube dir hilft keiner weil du eine Frau bist.
-
Vielen Dank für den qualifizierten Beitrag!
Zum Problem:
Ich konnte das Problem fast beseitigen. Ich kriege aber noch einen memory leak, weil ich m_bAutoDelete=false gesetzt habe und die Threads nicht mehr gelöscht werden. Wie kann ich den Thread manuell löschen, wenn er durchgelaufen ist?Da müsste doch irgendwas am Ende von meiner test_worker Funktion stehen.
-
Habe das Problem jetzt selbst gelöst.
Hier der Code (vielleicht interessiert es ja jemanden)bool Ctest_appDlg::run() { const int THREAD_COUNT = 10; data test[THREAD_COUNT]; HANDLE hThreads[THREAD_COUNT]; CWinThread *cThreads[THREAD_COUNT]; for(int i=0; i<THREAD_COUNT; i++) { test[i].i = i; test[i].p = this; cThreads[i] = ::AfxBeginThread(test_worker, &test[i], THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED); cThreads[i]->m_bAutoDelete = FALSE; cThreads[i]->ResumeThread(); hThreads[i] = cThreads[i]->m_hThread; } TRACE("\r\nAlle Threads gestartet. WARTE JETZT!"); ::WaitForMultipleObjects(THREAD_COUNT,hThreads,TRUE,INFINITE); for( i=0; i<THREAD_COUNT; i++ ) delete cThreads[i]; return true; }Grüße,
Julia
-
Jo! Du hast die Lösung selbst gefunden.
Dein Programm hat einfach nicht auf die Threads gewartet.