针对不同 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();