如何为每个线程分配队列容器实现多线程数据传递?
方案选型建议
现有方案的问题
你目前想到的存储裸指针的vector、自定义链表两种方案都存在明显缺陷:
- 裸指针没有生命周期管理,容易出现野指针、内存泄漏问题
- 自定义链表需要额外实现增删逻辑,如果你要在并发场景下操作这个链表,还要自己处理线程安全,完全没有必要
推荐方案(按场景选择)
场景1:线程数量固定,运行过程中不需要动态增删线程
直接使用存储智能指针的vector即可,是性能最高的方案:
std::vector<std::unique_ptr<concurrency::concurrent_queue<int>>> thread_queues;
优势:
std::unique_ptr自动管理队列的生命周期,不需要手动释放内存- vector支持O(1)随机访问,你可以直接按下标给对应线程分配队列,访问效率远高于链表
- 不需要自己实现任何容器逻辑,标准库实现已经做了极致优化
场景2:线程动态增减,需要频繁新增/销毁对应队列
推荐用unordered_map做线程ID到队列的映射:
// 线程ID可以用std::thread::id,也可以用你自己定义的线程编号 std::unordered_map<std::thread::id, std::unique_ptr<concurrency::concurrent_queue<int>>> thread_queues;
优势:
- 不需要维护队列的顺序,直接通过线程ID就能O(1)查找到对应队列,发送数据更方便
- 增删队列的逻辑由标准库容器实现,你只需要调用
insert/erase即可 - 如果你需要对整个队列集合做并发修改,只需要给unordered_map加一把互斥锁即可,比你自己维护链表的锁粒度更小、效率更高
额外优化建议
如果你的场景下不需要跨线程随机访问所有队列,仅需要在初始化时给每个线程分配专属队列,可以不用维护全局的队列集合:线程初始化阶段直接把队列的引用/右值传递给线程执行函数,由线程自己持有队列的访问权,完全避免全局集合的并发访问开销。
注意:不要尝试直接把concurrent_queue实例存到vector等容器中,并发队列通常不支持拷贝、移动操作,存实例会直接编译报错,存智能指针是最优选择
内容的提问来源于stack exchange,提问作者lampseeker
相关产品推荐
相关产品推荐

