针对不同 class 类型的并发 producer/consumer 队列设计
Concurrent producer/consumer queue design for different class types
我有两个线程 运行,其中生产者线程使用不同类型的更新将并发队列 (https://github.com/cameron314/readerwriterqueue.git) 排入队列,消费者线程根据更新类型。必须以正确的顺序处理这些更新。
我不想使用任何无法通过 CMake FetchContent 快速链接的附加依赖项。
我想到了这个,但我想知道是否有更好的方法来做到这一点:
enum UpdateType {
A,
B
};
class Update {
const std::shared_ptr<DataA> _dataA;
const std::shared_ptr<DataB> _dataB;
UpdateType _type;
public:
Update(std::shared_ptr<DataA> dataA) : _dataA(std::move(dataA)) {
_type = A;
}
Update(std::shared_ptr<DataB> dataB) : _dataB(std::move(dataB)) {
_type = B;
}
UpdateType GetType() const { return _type; }
std::shared_ptr<DataA> GetA() const { return _dataA; }
std::shared_ptr<DataB> GetB() const { return _dataB; }
};
auto queue = moodycamel::BlockingReaderWriterQueue<std::shared_ptr<Update>>(200);
Update a(std::make_shared<DataA>(DataA()));
Update b(std::make_shared<DataB>(DataB()));
queue.enqueue(std::make_shared<Update>(a));
queue.enqueue(std::make_shared<Update>(b));
std::shared_ptr<Update> q;
queue.wait_dequeue(q);
switch (q->GetType())
{
case A:
// Process A
break;
case B:
// Process B
break;
}
大概是这样的:
void ProcessA(std::shared_ptr<DataA> data);
void ProcessB(std::shared_ptr<DataB> data);
using UnitOfWork = std::function<void()>;
auto queue = moodycamel::BlockingReaderWriterQueue<UnitOfWork>(200);
// Producer
auto dataA = std::make_shared<DataA>();
queue.enqueue([dataA]() { ProcessA(dataA); });
auto dataB = std::make_shared<DataB>();
queue.enqueue([dataB]() { ProcessB(dataB); });
// Consumer
UnitOfWork w;
queue.wait_dequeue(w);
w();
我有两个线程 运行,其中生产者线程使用不同类型的更新将并发队列 (https://github.com/cameron314/readerwriterqueue.git) 排入队列,消费者线程根据更新类型。必须以正确的顺序处理这些更新。
我不想使用任何无法通过 CMake FetchContent 快速链接的附加依赖项。
我想到了这个,但我想知道是否有更好的方法来做到这一点:
enum UpdateType {
A,
B
};
class Update {
const std::shared_ptr<DataA> _dataA;
const std::shared_ptr<DataB> _dataB;
UpdateType _type;
public:
Update(std::shared_ptr<DataA> dataA) : _dataA(std::move(dataA)) {
_type = A;
}
Update(std::shared_ptr<DataB> dataB) : _dataB(std::move(dataB)) {
_type = B;
}
UpdateType GetType() const { return _type; }
std::shared_ptr<DataA> GetA() const { return _dataA; }
std::shared_ptr<DataB> GetB() const { return _dataB; }
};
auto queue = moodycamel::BlockingReaderWriterQueue<std::shared_ptr<Update>>(200);
Update a(std::make_shared<DataA>(DataA()));
Update b(std::make_shared<DataB>(DataB()));
queue.enqueue(std::make_shared<Update>(a));
queue.enqueue(std::make_shared<Update>(b));
std::shared_ptr<Update> q;
queue.wait_dequeue(q);
switch (q->GetType())
{
case A:
// Process A
break;
case B:
// Process B
break;
}
大概是这样的:
void ProcessA(std::shared_ptr<DataA> data);
void ProcessB(std::shared_ptr<DataB> data);
using UnitOfWork = std::function<void()>;
auto queue = moodycamel::BlockingReaderWriterQueue<UnitOfWork>(200);
// Producer
auto dataA = std::make_shared<DataA>();
queue.enqueue([dataA]() { ProcessA(dataA); });
auto dataB = std::make_shared<DataB>();
queue.enqueue([dataB]() { ProcessB(dataB); });
// Consumer
UnitOfWork w;
queue.wait_dequeue(w);
w();