C++调用Sender类关联std::thread::join()报非静态成员引用错误如何解决
问题原因
- 未将创建的
std::thread对象作为Sender类的成员变量存储,构造函数里的worker是局部临时对象,构造结束后就会被销毁,后续根本找不到要执行join操作的线程实例 - 直接调用
std::thread::join()属于试图调用std::thread的静态join方法,但实际上join是std::thread的非静态成员方法,必须绑定到具体的线程对象才能调用 - 构造线程时传入的执行入口参数错误,类的非静态成员函数作为线程入口时,需要同时传入成员函数指针和对应的类实例指针
- 静态成员
isFinished没有类外初始化,且多线程场景下普通bool存在可见性问题,需要改用原子类型保证线程安全
修复后完整代码
sender.h
#include <iostream> #include <thread> #include <atomic> #include <chrono> class Sender { public: // 改用原子bool保证多线程读写安全 static std::atomic<bool> isFinished; Sender() { // 绑定成员函数和当前实例指针,将线程存入成员变量 m_worker = std::thread(&Sender::SenderWorkflow, this); } void SenderWorkflow(); void join() { // 在线程实例可join的情况下执行等待操作 if(m_worker.joinable()) { m_worker.join(); } } private: // 存储工作线程的成员变量 std::thread m_worker; };
sender.cpp
#include <iostream> #include "Sender.h" // 类静态成员需要在类外初始化 std::atomic<bool> Sender::isFinished = false; void Sender::SenderWorkflow() { while (!isFinished) { std::cout << "Working... \n"; // 增加休眠避免输出刷新过快 std::this_thread::sleep_for(std::chrono::milliseconds(500)); } }
main.cpp
#include <iostream> #include "Sender.h" int main() { Sender mSender; // 主线程休眠1秒让工作线程执行一段时间 std::this_thread::sleep_for(std::chrono::seconds(1)); Sender::isFinished = true; mSender.join(); return 0; }
关键修改说明
- 给Sender类新增私有成员
std::thread m_worker,持久化存储构造时创建的工作线程实例,避免线程对象被提前销毁 - 构造线程时传入
&Sender::SenderWorkflow作为入口函数,同时传入this指针绑定当前类实例,符合非静态成员函数的调用要求 - join方法改为先判断成员线程是否可join,再调用
m_worker.join(),针对具体的线程实例执行等待操作 - 将静态的
isFinished改为std::atomic<bool>类型,避免多线程读写的可见性和竞态问题,同时补充类外初始化
内容的提问来源于stack exchange,提问作者Polar Bear
相关产品推荐
相关产品推荐

