如何在函数间传递包含std::mutex的ConcurrentQueue对象?
解决生产者-消费者模型中ConcurrentQueue的传参问题
你的问题核心是std::mutex不可拷贝,导致包含它的ConcurrentQueue类默认拷贝构造函数被删除,传值调用函数时触发编译错误。下面是几种实用的优化方案:
方案1:传递引用(最直接的解决方案)
直接将函数参数改为非const引用,这样不会拷贝ConcurrentQueue对象,而是直接操作原对象的内存,完美避开mutex拷贝问题。
修改后的代码示例:
#include <mutex> class ConcurrentQueue { std::mutex m; // 可补充队列存储、线程安全push/pop等核心方法 }; class Producer { public: // 参数改为引用 void func(ConcurrentQueue& a) { // 在此调用a的push方法实现生产逻辑 } }; class Consumer { public: // 参数改为引用 void func(ConcurrentQueue& a) { // 在此调用a的pop方法实现消费逻辑 } }; int main() { ConcurrentQueue a; Producer b; // 直接传引用,不会触发拷贝操作 b.func(a); // 后续创建消费者线程时,同样传递a的引用即可 return 0; }
注意:必须保证ConcurrentQueue对象的生命周期长于所有生产者/消费者线程,避免出现悬空引用导致的未定义行为。
方案2:使用智能指针(适合共享所有权场景)
如果需要多个线程长期共享队列,或者队列的生命周期不好直接管理,可以用std::shared_ptr包装ConcurrentQueue。传递智能指针时拷贝的是指针本身,不会触及内部的mutex。
修改后的代码示例:
#include <mutex> #include <memory> class ConcurrentQueue { std::mutex m; }; class Producer { public: void func(std::shared_ptr<ConcurrentQueue> a) { // 通过指针访问队列:a->push(...) } }; class Consumer { public: void func(std::shared_ptr<ConcurrentQueue> a) { // 通过指针访问队列:a->pop(...) } }; int main() { auto a = std::make_shared<ConcurrentQueue>(); Producer b; // 传递智能指针拷贝,所有线程共享同一个队列实例 b.func(a); // 消费者线程可直接传递同一个a return 0; }
这种方案的优势是无需手动管理队列的生命周期,当最后一个持有智能指针的线程结束时,队列会自动被销毁。
方案3:使用移动语义(适合所有权转移场景)
如果你的场景需要将队列的所有权完全转移给生产者/消费者(原对象不再使用),可以利用C的移动语义。std::mutex支持移动(C11及以后标准),因此ConcurrentQueue会自动生成默认的移动构造函数。
修改后的代码示例:
#include <mutex> class ConcurrentQueue { std::mutex m; }; class Producer { public: void func(ConcurrentQueue a) { // 操作被移动过来的队列实例 } }; int main() { ConcurrentQueue a; Producer b; // 使用std::move转移所有权,原对象a不再可用 b.func(std::move(a)); return 0; }
注意:移动后原对象a处于“有效但未定义”的状态,不能再对其进行操作,这种方案只适合明确需要转移所有权的场景。
内容的提问来源于stack exchange,提问作者Jerry
相关产品推荐
相关产品推荐

