如何处理多个源队列消息类型

时间:2017-10-26 19:31:57

标签: c++ multithreading concurrency message-queue race-condition

我对一般的并行编程有些新意,并试图理解如何处理我的系统等待的多种消息类型的情况。这个问题主要是为了简单地检查我的理解。我的特定系统是使用Microsoft并发运行时(C ++)实现的。

遇到其他两个SO问题 -

Google Protocol Buffers, how to handle multiple message-Types?

msmq multiple message types in a single queue

似乎通常的方法是创建一个代表所有不同子类型消息的公共消息。一些元数据包含在公共消息中,该消息确定特定的子类型消息。然后所有消息都通过一个队列传输;读取时,将根据消息元数据确定特定子类型,并执行相应的操作。

但是,在我的特定应用程序中,我宁愿能够使用专门用于每种类型消息的多个队列,然后等待所有这些消息,处理先获取消息的任何消息。但是,我可以看到这种方法引起的一些明显的阅读竞争条件 -

1)似乎不可能以与单独排队的顺序相同的顺序为不同类型的消息提供服务。问题

2)我可以想象两条消息同时可用。通过任何调度机制,一个被读取,另一个被...丢弃。失败。

仅这两个问题使我非常愿意放弃后一种方法。但是在我对我的小思想实验进行点燃之前,有没有人能够在多个源队列的防御中对抗上述两个问题?或者确实只能使用一个具有通用消息格式的队列?

1 个答案:

答案 0 :(得分:0)

如果你真的想要制作多个队列并拥有总订单,那么你需要一个票证系统,可能使用原子int(所有代码都是未经测试的)

int GetTicket() {
  static std::atomic<int> myTicket { 0 };

  return myTicket++;
}

然后按正确的顺序将它们从队列中剥离。

但是更容易使用std::function<WhatEver>队列的无锁队列,或者如果你想要一个简单的互斥保护队列,就像这样

#include <thread>             // std::thread
#include <mutex>              // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void EnQueue(std::function<WhatEver> func) {
  std::unique_lock<std::mutex> lck(mtx);
  myQueue.push_back(std::move(func));
  ready = true;

  cv.notify_one();
}



void print_id (int id) {
  while(true) {
    std::unique_lock<std::mutex> lck(mtx);
    while (!ready) cv.wait(lck);

    auto func = myQueue.front();
    myQueue.pop();

    func();
  }
}