【问题标题】:Why can't I kill pthread via class object argument passed in为什么我不能通过传入的类对象参数杀死 pthread
【发布时间】:2019-06-10 22:04:12
【问题描述】:

我启动了一个后台线程来运行我的类函数,该任务作为无限循环执行,直到客户端决定停止。因此,由于在创建 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);
   }

【问题讨论】:

  • Ted 下面的回答可能是正确的,但我建议用minimal reproducible example 扩充这个问题,这样他就可以证明是正确的,并且将来的提问者更容易在问题和答案之间建立联系。如果他是对的,请将-pedantic 添加到编译器选项中,您会收到一条很好的警告消息,建议您仔细查看Camera::_acquireImages,但如果您删除演员表,您会收到更好的消息。演员隐藏了你弄错的几件事。

标签: c++ linux pthreads


【解决方案1】:

所以自从创建 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(或更新版本),那么您应该看看标准的 &lt;thread&gt;,它让生活更轻松。

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

【讨论】:

  • 这应该保存为另一个针对演员表的警示故事:很多时候,他们隐藏了问题。
猜你喜欢
  • 2020-01-10
  • 2017-02-02
  • 1970-01-01
  • 2021-12-06
  • 1970-01-01
  • 1970-01-01
  • 2015-08-22
  • 1970-01-01
  • 2014-12-17
相关资源
最近更新 更多