Thread erzeugen.



  • Okay nach dem ich nun die FUnktion als thread aufrufen kann möchte ich auch auf die Klassen variblen zugreifen. Wie geht das ?

    Hier noch mal der Aufruf :

    HANDLE hThread[10];
    	int a = 10;
    	hThread[0] = CreateThread(NULL,0,test_thread,(void*)a,0,NULL);
    	WaitForMultipleObjects(1,hThread, true,INFINITE);
    

    Und die Definition :

    class cVolleyballTrainer
    {
    public:
    
    	cVolleyballTrainer(string odbc);
    	void Neues_Spiel();
    
    private:
    	static DWORD WINAPI test_thread(LPVOID pr);
    
    	cLiga *liga;
    };
    

    Und ich will jetzt auf

    liga
    

    zugreifen in meiner Threadfunktion . Wie gth das ??

    Vielen Dank



  • Habe ich oben beschrieben.



  • Okay. Ich habe mir deinen Beitrag noch einmal angesehen. Aber wenn ich das richtig sehe übergibts du der Funktion ja einen Paramter. Ich möchte aber ohne Paraterübergabe auf eine Variable zugriefen.

    Ist das überhaupt möglic ?



  • Nein, Deine Thread-Methode ist statisch, das heisst, sie ist von konkreten Objekt-Instanzen unabhängig.
    Um Zugriff darauf zu bekommen, musst Du einen this-Pointer übergeben.
    Btw. übergibst Du im Moment ja auch einen Parameter (int a).



  • Sofern Du die MS -CRT verwendest, solltest Du nicht CreateThread nutzen sondern _beginthreadex

    Ich vermute, aber, dass diesin anderen Compilern mit deren CRTs ähnlich ist.
    http://blog.m-ri.de/index.php/2007/11/28/createthread-und-die-crt/
    http://blog.m-ri.de/index.php/2008/02/28/afxbeginthread-versus-_beginthreadex/



  • GUten Morgen .
    Nachdem ich nun die Threads erzeugen konnte möchte ich nun auf ihre Abrabeitung warten.
    Ich erzeuege die Threads wie folgt :

    threadLiga *x = new threadLiga;
    	x = (threadLiga*)pr;
    
    	HANDLE hThread[5];
    	//cout<<x->iSpieltag<<"\n";
    	for (int i = 0; i < 5; i++)
    	{
    
    		threadLiga *temp = new threadLiga;
    		temp->iSpielnummer = i;
    		temp->iSpieltag = x->iSpieltag;
    		temp->pLiga = x->pLiga;
    
    		hThread[i] = CreateThread(NULL,0,Spiele_Match,(void*)temp,0,NULL);
    
    	}
    
    	WaitForMultipleObjects(5,hThread, true,INFINITE);
    

    MIt der Funktion Waitfor MultipleObjects warte ich auf das Ende der jeweiligen Threads leider kommt dabei eine Exception. Wenn ich in der Schleife auf die Beendigung warte( jeden einzelen) dann geht es .HAt jemand einen Idee.

    Vielen Dank



  • albert-einstein2 schrieb:

    Ich erzeuege die Threads wie folgt :

    threadLiga *x = new threadLiga;
    	x = (threadLiga*)pr;
    

    Schönes Speicherleck.

    albert-einstein2 schrieb:

    temp->pLiga = x->pLiga;
    

    Der Name pLiga deutet auf einen Zeiger hin. Wenn du nur einen Zeiger kopierst, dann benutzen alle Threads dasselbe Objekt. Ist das beabsichtigt, und hast du die Zugriffe synchronisiert?

    albert-einstein2 schrieb:

    MIt der Funktion Waitfor MultipleObjects warte ich auf das Ende der jeweiligen Threads leider kommt dabei eine Exception.

    Geht's etwas genauer als "eine Exception"?

    albert-einstein2 schrieb:

    Wenn ich in der Schleife auf die Beendigung warte( jeden einzelen) dann geht es

    Weil dann alle Threads nacheinander ablaufen. Dann hättest du dir die Threads auch sparen können. Also vermutlich wirklich ein Synchronisierungsproblem.



  • MFK schrieb:

    albert-einstein2 schrieb:

    Ich erzeuege die Threads wie folgt :

    threadLiga *x = new threadLiga;
    	x = (threadLiga*)pr;
    

    Schönes Speicherleck.

    Warum ist das ein Speicherleck ?

    Ansonsten hast du recht pLiga ist ein Zeiger. Ja das ist so beasichtigt. Der HIntergrund ist der : pLiga ist ein Zeiger auf eine Liga . Meine Thread Funtkion soll nun für diese Liga von einem bestimmten Spieltag (iSpieltag) alle Spiel ausführen (ebenfalls als Thread) deshalb müssen alle Thread sauf den gleiehn Zeiger zugriefen.



  • albert-einstein2 schrieb:

    Warum ist das ein Speicherleck ?

    An das Objekt, das du da mit new erzeugst, kommst du nie wieder ran, weil du gleich danach den Zeiger auf ein anderes Objekt umbiegst. Du kannst es also nie wieder freigeben -> Speicherleck.

    albert-einstein2 schrieb:

    Meine Thread Funtkion soll nun für diese Liga von einem bestimmten Spieltag (iSpieltag) alle Spiel ausführen (ebenfalls als Thread) deshalb müssen alle Thread sauf den gleiehn Zeiger zugriefen.

    Wie gesagt, du hast offenbar ein Synchronisierungsproblem. Für weitere Diagnose hast du nicht genug Informationen geliefert.



  • Okay danke für deine Antwort.

    Hier noch ein paar zusätzlich iNfos

    HANDLE hThread[1];
    
    	for (int i = 1; i <= liga->Get_Spieltag(); i++)
    	{
    		threadLiga *sp = new threadLiga;
    		sp->pLiga = liga;
    		sp->iSpieltag = i;
    
    		hThread[0] = CreateThread(NULL,0,test_thread,(void*)sp,0,NULL);
    
    	}
    
    	WaitForMultipleObjects(1,hThread, true,INFINITE);
    
    }
    
    // ==========================================
    
    DWORD WINAPI cVolleyballTrainer::test_thread(LPVOID pr)
    {
    	threadLiga *x = new threadLiga;
    	x = (threadLiga*)pr;
    
    	HANDLE hThread[5];
    	//cout<<x->iSpieltag<<"\n";
    	for (int i = 0; i < 5; i++)
    	{
    
    		threadLiga *temp = new threadLiga;
    		temp->iSpielnummer = i;
    		temp->iSpieltag = x->iSpieltag;
    		temp->pLiga = x->pLiga;
    
    		hThread[i] = CreateThread(NULL,0,Spiele_Match,(void*)temp,0,NULL);
    
    	}
    
    	WaitForMultipleObjects(5,hThread, true,INFINITE);
    
    	return 1;
    }
    
    // ==========================================
    
    DWORD WINAPI cVolleyballTrainer::Spiele_Match(LPVOID data)
    {
    	threadLiga *x = new threadLiga;
    	x = (threadLiga*)data;
    
    	//cout<<x->pLiga->Get_Ansetzungen(x->iSpieltag)[x->iSpielnummer]->pHeim->Get_Name()<<" "<<x->pLiga->Get_Ansetzungen(x->iSpieltag)[x->iSpielnummer]->pGast->Get_Name()<<"\n";
    	try
    	{
    		cMatch *ma = new cMatch(x->pLiga->Get_Ansetzungen(x->iSpieltag)[x->iSpielnummer]);
    		x->pLiga->Set_Ergebnis(ma->Get_Ergebnis());
    	}
    	catch(cException *ex)
    	{
    		cout<<ex->sError<<"\n";
    	}
    
    	return 1;
    }
    


  • Und weiter?
    Sind Get_Ansetzungen und Set_Ergebnis ordentlich synchronisiert, oder ist das Prinzip Hoffnung?
    Ist dir klar, dass du bei jedem Spiele_Match-Aufruf auch noch ein cMatch-Objekt erzeugst, das nie wieder freigegeben wird?

    Warum machst du das überhaupt mit Threads, und nicht einfach nacheinander?



  • Weil es 1. zu lange dauert. Und 2. Ich etwas lernen möchte.

    // ==========================================
    
    DWORD WINAPI cVolleyballTrainer::Spiele_Match(LPVOID data)
    {
    	threadLiga *x = new threadLiga;
    	x->iSpielnummer = ((threadLiga*)pr)->iSpielnummer;
    	x->iSpieltag = ((threadLiga*)pr)->iSpieltag;
    	x->pLiga = ((threadLiga*)pr)->pLiga;
    
    	//cout<<x->pLiga->Get_Ansetzungen(x->iSpieltag)[x->iSpielnummer]->pHeim->Get_Name()<<" "<<x->pLiga->Get_Ansetzungen(x->iSpieltag)[x->iSpielnummer]->pGast->Get_Name()<<"\n";
    	try
    	{
    		cMatch *ma = new cMatch(x->pLiga->Get_Ansetzungen(x->iSpieltag)[x->iSpielnummer]);
    		x->pLiga->Set_Ergebnis(ma->Get_Ergebnis());
    		delete ma;
    	}
    	catch(cException *ex)
    	{
    		cout<<ex->sError<<"\n";
    	}
    
    	return 1;
    }
    

    Wäre das so besser.
    Also mit dem Speicherlecks und dem Freigeben ?
    Vielen Dank



  • albert-einstein2 schrieb:

    Weil es 1. zu lange dauert. Und 2. Ich etwas lernen möchte.

    Wenn du von mehreren Fragen immer nur eine beantwortest, kommen wir nicht weiter.

    Und ganz nebenbei, durch Threads wird dein Programm nicht unbedingt schneller.



  • Ich denke schon. Da ja viele Objecte gleichzeit uasgeführet werden.

    Also Get_Ansetzung liefert einen Zeiger zurück bestehend aus den Ansetzungen für den jeweiligen Spieltag.



  • albert-einstein2 schrieb:

    Ich denke schon. Da ja viele Objecte gleichzeit uasgeführet werden.

    Ein Prozessorkern kann nicht mehrere Dinge gleichzeitig ausführen. Es wird immer wieder zwischen Threads hin- und hergeschaltet.

    albert-einstein2 schrieb:

    Also Get_Ansetzung liefert einen Zeiger zurück bestehend aus den Ansetzungen für den jeweiligen Spieltag.

    Ja, damit kann man nun gar nichts anfangen. Machst du da etwas, das synchronisiert werden müsste?

    Und die Frage, welche Exception geworfen wird, und an welcher Stelle, hast du immer noch nicht beantwortet.

    Und wenn du dein cMatch-Objekt sowieso gleich wieder freigibst, dann leg es doch bitte auf dem Stack an, nicht mit new.



  • Okay da hast natürlich Recht. Ich besitze aber einen Rechner mit mehrerer Kernen und da (so denke ich 9 ist ein UNterschied schon zu spüren. Außerdem bekommt eine Anwendung mehr Rechenzeit je mehr Prozesse sie laufen hat. Also selbst auf einem Single Kern Porzessor hast du einen Unterschied. Aber darum geht es huier ja nicht.

    Also die beiden Funktionen brauchen nicht synchronisiert werden. Ihc habe mal zum testen den Aufruf von cMatch rausgenbommen, und das gleiche bild geshen . also liegt der fehler woanders. ich habe die vermutung das das beenden der thread nicht so richtig klappt.

    gibt es da noch eine andere alternavtive ( funktion ) auf das ende eines threads zu warten



  • So ich habe jetzt noch eine interessante Entdekcung gemacht :

    HANDLE hThread[2];
    
    	for (int i = 0; i < 2; i++)
    	{
    		threadLiga *sp = new threadLiga;
    		sp->pLiga = liga;
    		sp->iSpieltag = i + 1;
    
    		hThread[i] = CreateThread(NULL,0,test_thread,(void*)sp,0,NULL);
    
    	}
    
    	WaitForMultipleObjects(2,hThread, true,INFINITE);
    
    }
    
    // ==========================================
    
    DWORD WINAPI cVolleyballTrainer::test_thread(LPVOID pr)
    {
    	threadLiga *x = new threadLiga;
    	x->iSpielnummer = ((threadLiga*)pr)->iSpielnummer;
    	x->iSpieltag = ((threadLiga*)pr)->iSpieltag;
    	x->pLiga = ((threadLiga*)pr)->pLiga;
    
    	cout<<"Spieltag : "<<x->iSpieltag<<" ";
    
    	HANDLE hThread[5];
    	//cout<<x->iSpieltag<<"\n";
    	for (int i = 0; i < 5; i++)
    	{
    
    		threadLiga *temp = new threadLiga;
    		temp->iSpielnummer = i;
    		temp->iSpieltag = x->iSpieltag;
    		temp->pLiga = x->pLiga;
    
    		hThread[i] = CreateThread(NULL,0,Spiele_Match,(void*)temp,0,NULL);
    
    	}
    
    	WaitForMultipleObjects(5,hThread, true,INFINITE);	
    
    	return 1;
    }
    
    // ==========================================
    
    DWORD WINAPI cVolleyballTrainer::Spiele_Match(LPVOID pr)
    {
    	threadLiga *x = new threadLiga;
    	x->iSpielnummer = ((threadLiga*)pr)->iSpielnummer;
    	x->iSpieltag = ((threadLiga*)pr)->iSpieltag;
    	x->pLiga = ((threadLiga*)pr)->pLiga;
    
    	//cout<<x->pLiga->Get_Ansetzungen(x->iSpieltag)[x->iSpielnummer]->pHeim->Get_Name()<<" "<<x->pLiga->Get_Ansetzungen(x->iSpieltag)[x->iSpielnummer]->pGast->Get_Name()<<"\n";
    /*	try
    	{
    		cMatch *ma = new cMatch(x->pLiga->Get_Ansetzungen(x->iSpieltag)[x->iSpielnummer]);
    		x->pLiga->Set_Ergebnis(ma->Get_Ergebnis());
    		//delete ma;
    	}
    	catch(cException *ex)
    	{
    		cout<<ex->sError<<"\n";
    	}*/
    
    	cout<<"\n"<<x->iSpielnummer<<"\n";
    
    	return 1;
    }
    

    Wenn ich nur einen Thread starte (test_thread) dann geht alles . Starte ich jedeoch 2 oder mehr kommt es wieder zum fehler. Und nun habe ich nur ausgaben.



  • albert-einstein2 schrieb:

    Starte ich jedeoch 2 oder mehr kommt es wieder zum fehler.

    Wie oft soll ich noch fragen, welcher Fehler?



  • Ja . Tut mir leid.

    Momnet der Fehler taucht nicht mehr auf. Kann es einen UNterschied im Debuig und Release modeus geben . Verwende Visual Stuio 6.0



  • albert-einstein2 schrieb:

    Kann es einen UNterschied im Debuig und Release modeus geben .

    Klar, wenn du unsauber programmiert hast. Uninitialisierte Variablen, Arraygrenzenüberschreitungen, falsche oder fehlende Synchronisation.


Anmelden zum Antworten