Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

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.

Geschrieben

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.

Geschrieben

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;

	}

Geschrieben

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?

Geschrieben
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

Geschrieben

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.

Geschrieben
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

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...