简体   繁体   中英

Why can't I kill pthread via class object argument passed in

I initiate a background thread to run my class function, the task is executed as an infinite loop until client side decide to stop. So since when create pthread the class object 'this' is passed into thread, I tried to cast it to class object but get a null object, can anyone explain to me why this is not workable ?

   void Camera::init()
   {
      typedef void *(*ThreadFuncPtr)(void *);
      this->quit=false;
      pthread_create(&acq, NULL, (ThreadFuncPtr)(&Camera::_acquireImages), this);
   }

   void Camera::stopAcquire()
   {
       this->quit=true;
   }

   void Camera::_acquireImages(void* ptr)
   {
       auto obj = (Camera*) ptr;  //obj after cast shows as NULL object
       while(!obj->quit){
       //do something
       }
       pthread_exit(NULL);
   }

So since when create pthread the class object 'this' is passed into thread

pthread_create is a C function and expects the function signature to be void* (*)(void*) but it now has the signature void (Camera::*)(void*) so there are two errors: The function should return void* and it's also a non-static class member. To fix it, make the function return void* and make it static :

void Camera::init()
{
    this->quit = false;
    // now that the function has the correct signature, you don't need
    // to cast it (into something that it wasn't)
    pthread_create(&acq, NULL, &Camera::acquireImages, this);
}

void Camera::stopAcquire()
{
    this->quit = true;
}

/*static*/ void* Camera::acquiredImages(void* ptr) // make it static in the declaration
{
    Camera& obj = *static_cast<Camera*>(ptr);

    while(obj.quit == false){
        //do something
    }
    return nullptr;
}

If you are using C++11 (or newer), you should however take a look at the standard <thread> which makes life much easier.

#include <thread>

struct Camera {
    void init() {
        quit = false;
        th = std::thread(&Camera::acquireImages, this);
    }
    ~Camera() {
        stopAcquire();
    }
    void acquireImages() {
        // no need for casting. "this" points at the object which started the thread
        while(quit == false) {
            std::cout << ".";
        }
    }
    void stopAcquire() {
        if(th.joinable()) {
            quit = true;
            th.join(); // hang here until the thread is done
        }
    }

    std::thread th{};
    bool quit = false;
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM