boost::thread und klassen methode



  • ich wollte einen boost::thread aus einer klasse heraus starten und diesem zur ausführung eine private methode der klasse zuweisen.

    scheinbar hab ich hier aber etwas noch nicht richtig verstanden.

    void TcpClientSocket::RsvThread (){
    ....}
    
    bool TcpClientSocket::Connect(){
           ......
           boost::thread thrd( &TcpClientSocket::RsvThread );
    }
    

    wie bau ich so etwas in eine ordentliche klassenstruktur in c++?

    lg



  • Meinem zugegebenermassen bescheidenen Wissnsstand nach laeuft da irgendwas mit boost::bind, um aus der Methode und dem Objekt, fur das sie aufgerufen wird, einen normalen Funktor zu machen, den der thread akzeptiert. Ueber die Suchfunktion solltest du fuendig werden, Fragen in der Art tauchen hier im Forum alle paar Wochen wieder auf.



  • das problem ist, dass eine memberfunktion einen this-zeiger braucht, also ein konkretes objekt, für das sie aufgerufen wird. boost::bind ist hier sehr flexibel und erkennt automatisch deine memberfunktion, du musst sie dann nur mehr an ein konkretes objekt binden:

    #include <boost/thread>
    #include <boost/bind>
    
    struct Foo
    {
       void bar ();
    };
    
    //...
    Foo instance;
    boost::thread t (boost::bind (&Foo::bar, &instance));
    


  • hm...
    naja ich hab es so probiert, weil ich mir so etwas schon gedacht habe:

    boost::thread thrd( boost::bind( &TcpClientSocket::RsvThread, this ) );
    

    aber das mit der instance klappt so wohl nicht.

    lg



  • ist this auch vom Typ TcpClientSocket* in deinem beispiel?

    ansonsten mal die explizite version probieren:

    void create_thead (TcpClientSocket& socket)
    {
       boost::thread t (boost::bind<void> (boost::mem_fn(&TcpClientSocket::RsvThread), boost::ref(socket));
    }
    

    ach: statt "klappt nicht" bitte fehlermeldungen angeben 😉



  • queer_boy schrieb:

    ist this auch vom Typ TcpClientSocket* in deinem beispiel?

    Da die Funktion die den Thread startet in seinem Fall eine Methode von TcpClientSocket ist, wird this wohl vom richtigen typ sein 😉



  • also ich poste mal den code dazu:

    void TcpClientSocket::RsvThread (int s){
      char * buffer = (char*) malloc (BUF);
      int size;
        long save_fd;
        do { 
          save_fd = fcntl( s, F_GETFL );
          save_fd |= O_NONBLOCK;
          fcntl( s, F_SETFL, save_fd );
          //lock_type lk( io_mutex );  
          	size = recv(s, buffer, BUF-1, 0);
    	  //lk.unlock();
          	if( size > 0){
             	buffer[size] = '\0';
          		printf ("Nachricht erhalten: %s\n", buffer);
          		}
          sleep(1);
          } while (1);
    }
    
    bool TcpClientSocket::Connect(){
    
      	if ((create_socket = socket (AF_INET, SOCK_STREAM, 0)) > 0)
        	printf ("Socket wurde angelegt\n");
    
      	address.sin_family = AF_INET;
      	address.sin_port = htons (portnr);
      	inet_aton (ipadr.c_str(), &address.sin_addr);
    
    	if (connect ( create_socket, (struct sockaddr *) &address, sizeof (address)) == 0){
        	printf ("Verbindung mit dem Server (%s) hergestellt\n", inet_ntoa (address.sin_addr));
        	info._socket = create_socket;
        	//io_mutex = new boost::mutex();
        	boost::thread thrd( boost::bind( &TcpClientSocket::RsvThread, this, create_socket) );
        	//boost::thread (boost::bind<void> (boost::mem_fn(&TcpClientSocket::RsvThread), boost::ref(this) ,boost::ref(create_socket)));
        	//boost::thread thrd( &this.RsvThread() );   
    		return true;
    	}
    	return false;
    }
    

    der fehlercode:

    /usr/lib/gcc/i486-linux-gnu/4.1.3/../../../../lib/crt1.o: In function _start': (.text+0x18): undefined reference tomain'
    ./clientsocket.o: In function TcpClientSocket::Connect()': /home/arnulf/workspace/clientsocket/Debug/../clientsocket.cpp:43: undefined reference toboost::thread::thread(boost::function0<void, std::allocatorboost::function_base > const&)'
    /home/arnulf/workspace/clientsocket/Debug/../clientsocket.cpp:46: undefined reference to `boost::thread::~thread()'
    collect2: ld gab 1 als Ende-Status zurück
    make: *** [clientsocket] Fehler 1

    ich weiß es gibt noch keine ausstiegsbedinung und vieles mehr ist ja noch nicht fertig.

    wie ich dann die boost::mutex da rein bringe ist eine andere frage.
    ich hab alles mögliche probiert was mir so eingefallen ist.

    lg



  • Ich sehe hier keinerlei Compilerfehler, nur einen Linkerfehler. Eigentlich hast Du nur vergessen, die boost::thread-Bibliothek mitzulinken.

    EDIT: Eine main-Funktion fehlt offensichtlich auch.



  • ok ich bin ein dödel.
    hab eclipse nicht gesagt wo die boost libs liegen.

    man das kommt davon wenn man managed make verwendet.

    lg



  • Neben den Includes braucht boost::thread auch noch eine Bibliothek - die muss beim gcc mit -l dazugebunden werden. Allerdings weiss ich den Namen der Bibliothek nicht auswendig, da der von einigen Faktoren wie der Compilerversion abhängt.



  • pthread soweit ich weiß.
    habs jedenfalls dazu gelinkt.
    lg und danke



  • autolink geht bei boost AFAIK nur mit msvc.



  • Funktioniert auch beim BCB.



  • Nein, nicht pthread, sondern boost::thread...
    boost::thread selbst braucht wiederum pthreads, ja, aber "undefined reference to `boost::thread::~thread()`" kommt sicher nicht aus einer C-Bibliothek 😉



  • Wäre schon eine komische C-Bibliothek 🙂


Anmelden zum Antworten