Posix Thread C++ Verzweiflung pur!!!!



  • Hosa zusammen.....

    ich verzweifle seit einigen Stunden daran Posix Threads in mein Programm einzubauen. Das Programm berechnet die Mandelbrotmenge und zeichnet es dann als Ascii auf der Konsole oder in SDL.

    Mein Problem ist jetzt das die Berechnung der einzelnen Punkte (für die jedes mal 10000 Iterationen durchgeführt werden) gerne auf n Posix Threads aufteilen würde.
    Der Rahmen dazu sollte stimmen allerdings meckert der Compiler bei pthread_create bei der Funktionsübergabe.

    Der Fehler sieht so aus :
    mandelbrotPosix1.cpp:135: error: argument of type ‘void* (CMandelbrot::)(void*)’ does not match ‘void* ()(void)’

    und hier der Quellcode:

    der Klasse

    Class CMandelbrot
    {
    public:
    	CMandelbrot(int nrIterations);
    	int getAsciiMapPoint(int x, int y){return asciiMap[x][y];}
    	int getSdlMapPoint(int x, int y){return sdlMap[x][y];}
    
    	void iniPosixThreads(int outputMode); //initialisierung von posix
    	void* calcAsciiSet(void* pThreadNum); //funktionen die übergeben werden 
    	void* calcSdlSet(void* pThreadNum);   //sollen
    

    die Funktion

    void* CMandelbrot::calcAsciiSet(void* pThreadNum)
    {	int* threadNum = (int*)pThreadNum;
    	printf("Thread %i started\n",*threadNum);
    	unsigned begin,end; // stores start and endpoint of the threads
    	if(*threadNum == -1) // only one thread, so no POSIX-threads to create
    	{
        		begin = 0;
        		end = ASCII_HEIGHT;
    	}
     	else //calculates the start end endpoint of the thread
        	{
        	begin = (ASCII_HEIGHT/numThreads)*(*threadNum);
        	end = (ASCII_HEIGHT/numThreads)*(*threadNum+1);
    	}
    	for (unsigned i = begin; i < end; i++)
    		for (int j = 0; j < ASCII_WIDTH; j++)
    			asciiMap[j][i] = inSet(minRe + (maxRe - minRe) * j / (ASCII_WIDTH - 1), -minIm + (2 * minIm) * i / (ASCII_HEIGHT - 1));
    }
    

    und das ist der Knackpunkt wo sich der compiler quer stellt

    void CMandelbrot::iniPosixThreads(int outputMode)
    {
    	if(numThreads==1) // no POSIX-threads need to be created
    	{	int noThreads = -1;
    		if(outputMode == 1)			
    			calcAsciiSet((void*)&noThreads);
    		else	calcSdlSet((void*)&noThreads);
    	}
    	else if(numThreads>1)
    	{
    		threads = (pthread_t*)malloc(numThreads*sizeof(pthread_t)); // reserve memory for the threads
    		threadNums = (int*)malloc(numThreads*sizeof(int)); // reserve memory for the thread-numbers
    		if (outputMode == 1)
    		{
    			for (unsigned i=0;i<numThreads;i++)
    			{
    				threadNums[i] = i;
    
    		               <<HIER|HIER|HIER>>		pthread_create(&threads[i],NULL,calcAsciiSet,(void *)&threadNums[i]); // create thread
    .........
    

    Meine bisherige Recherche hat ergeben das die funktion calcAsciiSet/calcSdlSet global deklariert oder static sein müsste damit pthread_create(.... nicht mehr mosert. Static geht aber nicht weil die werte ja dynamisch sind und das ganze nochmal global zu schreiben wäre ein riesen Aufwand. Hoffe es gibt noch eine andere Möglichkeit es zum laufen zu bringen.

    Danke schonmal für die Hilfe.
    Gruß Zimbo



  • Du solltest auch die Ausgabe des Compilers posten!

    Du kannst nicht einfach eine Methode übergeben und erwarten das es klappt. Eine Methode braucht ja immer ein passendes Objekt und ist daher nicht wie eine Funktion einfach als Funktionspointer benutzbar. Am einfachsten könntest du das ganze so realisieren:

    class Mandelbrot { // kein C Prefix. das ist doch hässlich!
      static void* call_calcAsciiSet(void *obj) {
         Mandelbrot *self = reinterpret_cast<Mandelbrot*>(obj);
         return self->calcAsciiSet();
      }
    
    // ...
    
       pthread_create(&threads[i], NULL, Mandelbrot::call_calcAsciiSet, (void *)this);
    

    und in C++ benutzt man doch kein malloc mehr!



  • Das leuchtet mir ein aber irgendwie passt es ihm immernochnicht!
    Das spuckt der compiler jetzt aus:

    nc10@nc10-laptop:~/Desktop/p5$ g++ -lSDLmain -lSDL -lSDL_ttf -Llib -o mandelbrot mandelbrotPosix1.cpp
    mandelbrotPosix1.cpp: In static member function ‘static void* CMandelbrot::call_calcAsciiSet(void*)’:
    mandelbrotPosix1.cpp:38: error: expected primary-expression before ‘void’
    mandelbrotPosix1.cpp: In static member function ‘static void* CMandelbrot::call_SdlSet(void*)’:
    mandelbrotPosix1.cpp:43: error: expected primary-expression before ‘void’
    mandelbrotPosix1.cpp: In member function ‘void CMandelbrot::iniPosixThreads(int)’:
    mandelbrotPosix1.cpp:155: error: ‘call_calcSdlSet’ is not a member of ‘CMandelbrot’
    


  • So jetzt funzts...vielen Dank für deine Hilfe!!!
    Hab return self->calcAsciiSet(obj); nochmal das obj mitgegeben und jetzt compiliert er!!!


Anmelden zum Antworten