C++ 事件驱动模拟器中同时发生的事件

C++ 事件驱动模拟器中同时发生的事件,c++,event-driven,event-driven-design,C++,Event Driven,Event Driven Design,我一直在尝试开发一个简单的事件驱动模拟器,从这里开始 当我对示例进行一些修改时,我遇到了这样一种情况:当两个事件(到达、离开)同时发生时(比如在时间单元5),模拟器就会弹出事件队列顶部的任何内容,如下面的代码段所示 void simulation::run () { while (! eventQueue.empty ()) { event * nextEvent = eventQueue.top (); eventQueue.pop (); time = nextEvent->ti

我一直在尝试开发一个简单的事件驱动模拟器,从这里开始

当我对示例进行一些修改时,我遇到了这样一种情况:当两个事件(到达、离开)同时发生时(比如在时间单元5),模拟器就会弹出事件队列顶部的任何内容,如下面的代码段所示

void simulation::run () {

while (! eventQueue.empty ()) {

event * nextEvent = eventQueue.top ();
eventQueue.pop ();
time = nextEvent->time;
nextEvent->processEvent ();
delete nextEvent;
  }
}
如果两个事件同时发生,我如何强制执行在出发事件之前始终弹出某个事件(首先到达事件)的条件


非常感谢您的帮助

我假设
eventQueue
具有所描述的类型(因为您的问题中的链接引用了该类型)。从那里,您可以阅读
top()

返回对队列中具有最高优先级的元素的常量引用

。。。而那
pop()

从队列中删除具有最高优先级的项

因此,从您的问题中提取代码,最明显的方法是将所有具有相同时间的事件从队列中取出,然后再进行处理:

while (! eventQueue.empty ()) {
  event * ev = eventQueue.top (); // WHY do you have pointers here ?!?!?
  time = ev->time;
  some_container<event *> arrivals, departures;
  // Take out all events that happen "now" from the queue
  while (time == ev->time) {
    eventQueue->pop();
    if (ev->type == ARRIVAL) {
      arrivals.push_back(ev);
    } else {
      departures.push_back(ev);
    }
    ev = eventQueue->top();
  }
  // Process arrivals
  for (event * e : arrivals) {
    e->processEvent();
    delete e; // Again: WTF pointers? raw? NOT a good idea!
  }
  // Process departures
  for (event * e : departures) {
    e->processEvent();
    delete e;
  }
}
因此,这里更好的方法是使用自定义比较函数对象在所有事件之间建立总顺序:

// sigh ... pointers ... raw pointers ... just WHY???!?
template<typename Event>
struct less_event_ptr {
  std::less<time_type> time_compare; // time_type hopefully is self-describing ...
  bool operator()(Event * lhs, Event * rhs) const {
    if (time_compare(lhs->time, rhs>-time)) {
      return true;
    }
    if (time_compare(rhs->time, lhs->time)) {
      return false;
    }
    if (lhs->type == ARRIVAL && rhs->type == DEPARTURE) {
      return true;
    }
    return false;
  }
};

如果需要可复制的模拟,“时间”是事件的顺序。不存在两件事同时发生的情况。好吧,我接受你的观点。但我仍然有一个问题,如果两个事件的时间相同,会发生什么?我们能确定哪件事先发生吗?通过剩下的模拟。谢谢如果两个事件同时发生,那就是一个bug。它不应该发生在一个正常运行的系统中。请考虑一个情况,其中一些数据包到达系统,并根据某些随机过程离开系统。在这种情况下,第(n+1)个分组到达事件可以与第n个分组离开事件具有相同的时间。因此,我无法接受这是一个错误。系统可以具有这样的属性。我相信事件驱动模拟可以处理这种情况。使用优先级队列-按2个因素排序-从更重要的方面:1)时间2)事件类型。对了。你好,丹尼尔,谢谢你的回复。目前,我必须处理同时发生的多个到达/离开事件。我正在检查这个,很快会给你回复。你好,丹尼尔,我能理解你给出的解决方案。我试着提出一个最小的、完整的、可验证的例子,这样我就可以尝试你的答案并接受它。下面是一个简单的代码片段(),它复制了我刚才提到的问题。你能帮我整合你的代码,这样我就可以测试它并接受你的答案吗。谢谢
// sigh ... pointers ... raw pointers ... just WHY???!?
template<typename Event>
struct less_event_ptr {
  std::less<time_type> time_compare; // time_type hopefully is self-describing ...
  bool operator()(Event * lhs, Event * rhs) const {
    if (time_compare(lhs->time, rhs>-time)) {
      return true;
    }
    if (time_compare(rhs->time, lhs->time)) {
      return false;
    }
    if (lhs->type == ARRIVAL && rhs->type == DEPARTURE) {
      return true;
    }
    return false;
  }
};
std::priority_queue<event *, std::vector<event *>, less_event_ptr<event>> eventQueue;