c++ - 用于创建类生成线程的多个实例的 C++ 线程模型
问题描述
抽象的:
我正在设计一个类 ( Inner
),它产生 2 个线程——一个生产者和一个消费者。在一种用法中有一个实例,而在另一种情况下有多个实例。
在 Standalone 中,我需要两个线程来继续写入/读取消息。但是,如果有多个实例,我需要代码来生成两个线程,但继续创建下一个类(以生成更多线程)。
我的问题是尝试将这两种情况与正确使用std::thread::join()
和结合起来std::thread::detach()
。
代码详情:
该类Inner
产生一个线程来接收和排队消息,以及第二个线程来读取队列并将消息发送到拥有的类Inner
。
template<Owner>
class Inner
{
Inner(Owner& owner) : _owner(owner)
{
// Spawn thread to receive packets and put on queue
// Spawn thread to read from queue
}
void receiveMessage(const Message& msg)
{
// Ommitted locks etc for simplicty
_queue.push(msg);
}
void readFromQueue()
{
// Ommitted loop, locks etc for simplicty
_owner.receiveMessage(msg);
}
Owner& _owner;
std::queue<Message> _queue;
};
有两种可能的所有者类别SingleInner
:
class OneInner
{
OneInner()
{
_inner = std::make_unique<Inner>();
}
void receiveMessage(const Message& msg){//Code ommitted}
std::unique_ptr<Inner> _inner;
};
第二个上下文有多个实例:
class MultipleInners
{
MultipleInners()
{
// Need to create multiple instances of Inner, each with Inner's two threads running
}
void receiveMessage(const Message& msg){//Code ommitted}
std::vector<std::unique_ptr<Inner>> _inners;
};
我不确定如何允许Inner
生成 2 个线程,让它们继续运行,但在OneInner
代码中等待并且在MultipleInners
代码中继续创建下一个Inner
.
或者是否有更好的方法来实现这一目标?
解决方案
对于类的每个实例都需要一个资源,并且其生命周期与匹配实例的生命周期相同,最好将其表示为成员变量。
所以只需让线程成员变量Inner
在构造时启动,并在销毁时加入:
template<Owner>
class Inner
{
Inner(Owner& owner)
: _owner(owner)
, _recv_thread([this](){readFromQueue();}),
, _read_thread([this](){receiveLoop();}),
{
}
~Inner() {
_recv_thread.join();
_read_thread.join();
}
void receiveLoop() {
while(...) {
//etc...
receiveMessage(msg);
}
}
void receiveMessage(const Message& msg)
{
// Ommitted locks etc for simplicty
_queue.push(msg);
}
void readFromQueue()
{
// Ommitted loop, locks etc for simplicty
_owner.receiveMessage(msg);
}
Owner& _owner;
std::queue<Message> _queue;
// Make sure these are the last members, so that _owner and _queue
// are constructed already when the threads start
std::thread _recv_thread;
std::thread _read_thread;
};
推荐阅读
- timeout - Hystrix 配置:isolation.thread.timeoutInMilliseconds
- laravel - “您要查找的资源已被删除、名称已更改或暂时不可用”Azure 上的 Laravel
- node.js - 我在 ./node_modules/@coreui/angular/fesm5/coreui-angular.js 493:33-51 "export 'ɵɵdefineInjectable' is not found in '@angular/core' 中收到警告
- jira - jira 云实例中问题附件的临时链接/url
- c# - 如何使 Ibeacon estimode 统一检测所有信标
- python - 在 Keras 中进行 BatchNorm 配置编辑后无法重新加载模型
- character - ~|的意思 以 Common Lisp 格式
- ssl - 将“A”记录作为子域添加到 IP 会删除 HTTPS?
- php - 将带有星号的文本列表替换为 ul li [php]
- bash - rdd.pipe 为 grep -i shell 命令抛出 java.lang.IllegalStateException?