Почему я не могу уничтожить pthread с помощью аргумента объекта класса, переданного в - PullRequest
0 голосов
/ 11 июня 2019

Я запускаю фоновый поток для запуска моей функции класса, задача выполняется в виде бесконечного цикла, пока клиентская сторона не решит остановиться.Поэтому, так как при создании pthread объект класса 'this' передается в поток, я пытался привести его к объекту класса, но получить нулевой объект. Может кто-нибудь объяснить мне, почему это не работает?

   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);
   }

1 Ответ

4 голосов
/ 11 июня 2019

Итак, поскольку при создании pthread объект класса 'this' передается в нить

pthread_create является функцией C и ожидает, что сигнатура функции будет void* (*)(void*), но теперь она имеет сигнатуру void (Camera::*)(void*), поэтому есть две ошибки: функция должна возвращать void*, и это тоже не статический член класса. Чтобы исправить это, сделайте функцию, возвращающую void*, и сделайте ее 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;
}

Если вы используете C ++ 11 (или новее), вам следует взглянуть на стандарт <thread>, который значительно облегчает жизнь.

#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;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...