【问题标题】:Concurrent producer/consumer queue design for different class types不同类类型的并发生产者/消费者队列设计
【发布时间】:2021-02-07 15:43:50
【问题描述】:

我有两个线程正在运行,其中生产者线程使用不同类型的更新将并发队列 (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;
}

【问题讨论】:

  • 您可以使用std::variant
  • 谢谢,我选择了 Igors 方法。

标签: c++ types collections concurrency queue


【解决方案1】:

大概是这样的:

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();

【讨论】:

  • 感谢您的反馈,这种方法效果很好。
猜你喜欢
  • 2012-01-28
  • 1970-01-01
  • 2011-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多