phtreads... korrekt beenden.



  • hi,

    ich nutze eine globale Variable...

    bool exit_ptread = false;
    
    void wait ( int seconds )
    {
      clock_t endwait;
      endwait = clock () + seconds * CLOCKS_PER_SEC ;
      while (clock() < endwait) {}
    }
    

    dann meine Thread-Funktion...

    void* move_objects( void * ptr)
    {
       ...
       while(!exit_ptread){		 
          ...
    
       }
    
    }
    

    dann in meiner main

    int main() {
         ...
         case end_moving:
           exit_ptread = true;				
           wait(4);
           cout << "---closing................" <<endl;
           break;
         return 0; 
      }
    

    Ich meine es funktioniert. Aber ist das elegant? Und nicht Fehleranfallig?
    Ich möchte aber auch nicht da mein Haupthtread (..main..) blockiert...

    Gruß
    Franky



  • Ich weiß ja nicht, was du da tust, aber statt deiner selbst geschriebenen Funktion wait solltest du sleep nehmen. Außerdem musst du sowieso mit pthread_join deinen Thread wieder einsammeln, sonst bleiben Reste im Speicher zurück. (Außer du machst ein "detach")

    Was du also tust ist, deine variable exit_ptread auf true setzen und dann mit man: pthread_join deinen Thread einsammeln.



  • Du solltest dir mal

    int pthread_mutex_lock(pthread_mutex_t *mutex);
    int pthread_mutex_trylock(pthread_mutex_t *mutex);
    int pthread_mutex_unlock(pthread_mutex_t *mutex);
    

    angucken. Da kannst du sauber Variablen in unterschiedlichen Threads benutzen und trylock blockiert auch nicht...



  • Hi,

    Ok, Danke für die Antworten. Die Tipps habe ich mir angesehen.
    Habe dann mal das Projekt auf Ubuntu portiert um mal ein bischen zu testen (mit den Threads). Dort habe ich allerdings ein Problem...
    Ich kann nicht linken....

    #include "AccServer.h"
    #include <pthread.h>
    #include <iostream>
    
    bool stop_working = false;
    
    void* thread_function1( void* ptr)
    {
    	while( !stop_working ){
    		std::cout << "thread" << std::endl;
    	}
    	return NULL;
    }
    
    int main( void ) {
    	pthread_t thread1;
    
    	pthread_create( &thread1,
    					NULL,
    					thread_function1,
    					NULL);
    
    	return 0;
    }
    

    Makefile

    CCFLAGS = -Wall -Wextra -W -ansi
    CCTHREAD =  -lpthread
    COMPILE = g++
    
    all: AccServer.o \
    		--LINK=c++  -lstdc++ -lpthread -o $(HOME)/workspace/AccServer/AccServer
    
    AccServer.o:			AccServer.h	\
    				$(COMPILE) $(CCFLAGS)  AccServer.cpp -c 
    
    clean:
    		rm -f *.o
    

    Dann der output...

    **** Build of configuration Debug for project AccServer ****

    make all
    Building file: ../AccServer.cpp
    Invoking: GCC C++ Compiler
    g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"AccServer.d" -MT"AccServer.d" -o"AccServer.o" "../AccServer.cpp"
    ../AccServer.cpp: In function ‘int main()’:
    ../AccServer.cpp:24: warning: unused variable ‘ret1’
    Finished building: ../AccServer.cpp

    Building target: AccServer
    Invoking: GCC C++ Linker
    g++ -o"AccServer" ./AccServer.o
    ./AccServer.o: In function main': /home/myPath/workspace/AccServer/Debug/../AccServer.cpp:33: undefined reference topthread_create'
    collect2: ld returned 1 exit status
    make: *** [AccServer] Error 1

    Gruß
    Franky



  • ich glaube der schlüssel ist -lpthread. Ich würde vermuten es steht an der falschen Stelle, schreibe meine makefiles allerdings nicht selbst. Ich benutze Anjuta bei mir steht es unter linker-flags. Das ist IMO nicht da wo es bei dir steht.



  • Trigger_Hurt schrieb:

    ich glaube der schlüssel ist -lpthread.

    Ich meine, es war nur -pthread, also ohne das "L".



  • Ja,

    ich denke das muß so...

    CCFLAGS = -Wall -Wextra -W -ansi -lpthread
    

    oder ich nehme -mthread oder -mthreads oder -pthread
    Option. Auf dem anderen System habe ich...

    DEBUG     = -g -D_POSIX_PTHREAD_SEMANTICS
    

    Das sollte dann dort stehen..

    $(COMPILE) $(CCFLAGS) $(DEBUG) AccServer.cpp -c
    

    und das dann beim --LINK weg... Lib's habe ich in Eclipse allerdings keine extra angegeben. Kann ich allerdings erst heute abend zu Hause testen.



  • So,

    habe das jetzt so gemacht...

    void* thread_function1( void* ptr)
    {
        int break_flag = 0;	   
        //damit ich hier keine globale Variable....
        while( !break_flag ){
    
            rc = pthread_mutex_trylock (&lock);	
            if ( stop_working && rc == 0 ){	
                    //			
    		break_flag = stop_working;				
    	    }
            //mutex unlock!!!!
            pthread_mutex_unlock (&lock);			
    
            // Mutex ist jetzt frei...		
    	if( break_flag ) break;   
    
            get_timestamp_server(time_stamp, &objs);
            std::cout << "thread" << std::endl;
    
        }
        return NULL;
    }
    

    in der main...

    int main( void ) {
        pthread_t thread1;
        ...
        pthread_create( &thread1,
                        NULL,
                        thread_function1,
                        NULL);
        ...
    
        case EXIT:{
            int rc;
    	while( (pthread_mutex_trylock( &lock )) == EBUSY) {
    		sleep( 4 );
    	}       
            exit_ptread = true;					
    	pthread_mutex_unlock(&lock);	
            sleep(5);
    	rc = pthread_join(tthunder, &pthread_status);
    	if (rc){
    	     printf("ERROR; return code from pthread_join() is %d\n", rc);
    	     exit(-1);
            }
    	cout << "---closing................" <<endl;
            exit(0);
         }
         break;
    
        return 0;
    }
    

    Ich hoffe das ist besser zumindest der Zugriff auf die globale Variable...

    Gruß
    Franky


Anmelden zum Antworten