TinTin Geschrieben 17. März 2006 Teilen Geschrieben 17. März 2006 Servus Gemeinde, ich suche nach einer Möglichkeit einen CString als Parameter in eine ThreadFunktion zu übergeben. Bei CreateThread steht mir ja LPVOID als Paremeter zu Verfügung. Wie bekomme ich den dazu einen CString zu akzeptieren? TinTin DWORD WINAPI threadCreateZip(CString test) { AfxMessageBox(test); return 0; } CreateThread(NULL, 0, threadCreateZip, test, NULL, &ThreadId); So gehts natürlich nicht, aber so sollte es im Prinzip aussehen. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 17. März 2006 Teilen Geschrieben 17. März 2006 Du kannst jeden beliebigen Zeiger in den Thread reingeben, und dann im Thread durch einen passenden Cast wieder rausholen. Du musst nur darauf achten, dass die Lebensdauer des Objekts, dessen Adresse du übergibst, lang genug ist. Die Adresse eine Autovariablen zu benutzen, ist also meist eine ziemlich schlechte Idee. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
TinTin Geschrieben 17. März 2006 Autor Teilen Geschrieben 17. März 2006 Danke, so schauts aus. typedef struct threadArgs { LPCTSTR lpDBPath; LPCTSTR lpZipName; } threadArgs; DWORD WINAPI threadCreateZip(LPVOID lParam) { threadArgs *ta; ta = (threadArgs*) lParam; TRACE("arg1:%s arg2:%s",ta->lpZipName,ta->lpDBPath); return 0; } ... HANDLE hThread = CreateThread(NULL, 0, threadCreateZip, (LPVOID)&ta, NULL, &ThreadId); if (hThread != INVALID_HANDLE_VALUE) { WaitForSingleObject(hThread, INFINITE); DWORD dwExitCode; GetExitCodeThread(hThread, &dwExitCode); CloseHandle(hThread); return; } Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 18. März 2006 Teilen Geschrieben 18. März 2006 Drei Anmerkungen: Wie ist ta deklariert? Ist das eine lokale Variable? Falls ja, könnte das zu den oben erwähnten Problemen führen, falls du mal nicht auf das Ende des Threads wartest. Zweitens: Wenn du Zeiger in deiner threadArgs-Struktur benutzt, gilt für die Lebensdauer der Objekte, auf die diese Zeiger verweisen, das gleiche wie für die Struktur selbst. Und drittens ist ein Thread ziemlich sinnlos, wenn du gleich nach dem Starten auf das Ende wartest. Oder war das nur ein Beispiel? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
TinTin Geschrieben 18. März 2006 Autor Teilen Geschrieben 18. März 2006 Wie ist ta deklariert? Ist das eine lokale Variable? Falls ja, könnte das zu den oben erwähnten Problemen führen, falls du mal nicht auf das Ende des Threads wartest. ta ist lokal in einer Dialogklasse deklariert, beinhaltet aber 'nur' zwei Pfade, die direkt inder TreadFunktion genutzt werden. kann ich aber auch global deklarieren. Zweitens: Wenn du Zeiger in deiner threadArgs-Struktur benutzt, gilt für die Lebensdauer der Objekte, auf die diese Zeiger verweisen, das gleiche wie für die Struktur selbst. Was ist denn sinnvoller, denn meinem Code sind die ta-Member Zeiger auf zwei Klassen-Menbervariablen threadArgs ta; ta.lpDBPath = m_csDBFullPath; ta.lpZipName = m_csFullBackUpPath; Und drittens ist ein Thread ziemlich sinnlos, wenn du gleich nach dem Starten auf das Ende wartest. Oder war das nur ein Beispiel? Ist nur ein Beispiel und WaitForSingleObject(hThread, INFINITE); hat da auch Nichts mehr zu suchen TinTin Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 18. März 2006 Teilen Geschrieben 18. März 2006 Mal zwei Beispiele: int foo() { threadArgs ta; CreateThread(&bar, &ta); // Stark vereinfacht // <- hier wird ta zerstört } int bar(void* param) { threadArgs* ta = (threadArgs*)param; // <- gibt es das Objekt überhaupt noch? }[/code] Du kannst hier nicht sicher sein, dass die lokale Variable ta in foo überhaupt noch existiert, wenn du im Thread bar die Adresse rausholst. Das ist genauso böse wie das Zurückgeben der Adresse einer lokalen Variablen. 2. Beispiel [code]class someclass { threadArgs m_ta; int foo() { CreateThread(&bar, &m_ta); // Stark vereinfacht m_ta.m_intMember++; } }; int bar(void* param) { threadArgs* ta = (threadArgs*)param; int wichtig = ta->m_intMember; // <- Welcher Wert landet hier? }Hier ist die Lebensdauer kein Problem. Aber du kannst nicht wissen, ob zuerst im someclass::foo der int-Member erhöht, oder im Thread bar ausgelesen wird. Dieses Problem tritt immer dann auf, wenn du die Threadparameter ändern könntest - wie in deinem Fall. Und es ist natürlich Quatsch, Adressen von globale Variablen als Threadparameter zu übergeben. An globale Variablen kommst du ja auch so ran. Wenn du nicht ganz sicher bist, dass das Parameterobjekt lange genug lebt und unveränderlich ist - zumindest bis der Thread eine Kopie anlegen konnte - solltest du entweder Synchronisierungsobjekte benutzen oder die Parameter für jeden einzelnen Thread auf dem Heap anlegen. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
TinTin Geschrieben 21. März 2006 Autor Teilen Geschrieben 21. März 2006 Und es ist natürlich Quatsch, Adressen von globale Variablen als Threadparameter zu übergeben. An globale Variablen kommst du ja auch so ran. Wie Recht du hast ich war wohl geistig etwas verwirrt. Das mit den Syncronisierungsobjekten sieht ganz interessant aus, ist mir für den Moment aber zu aufwendig. Ich lege die Parameter auf den Heap, dass sollte für den Moment reichen. Danke für Deine Hilfe, TinTin Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.