C / C ++中事件循环的实现,在调用堆栈上很好用

时间:2015-10-24 23:04:19

标签: c++ c event-loop

TL; DR

C / C ++中管理调用堆栈的事件循环的最佳实现是什么?

  • 为什么?
  • 基准/比较?
  • 文献/出版物/文档?

事件循环,问题

他们是一个简单的概念:等待事件,处理事件,等待更多事件。

我回顾了一些旧的项目并遇到了一个简单(有点差)的搜索引擎实现,我的好奇心引发了正确的方式来做事件循环。

当时我做了类似这样(非常)的简化示例:

int wait_for_query();
int handle_query();

int main(int argc, const char** argv) {
  return wait_for_query();
}

int wait_for_query() {
  // Do some stuff
  return handle_query();
}

int handle_query() {
  // Handle it
  // if query is quit, return quit();
  return wait_for_query();
}

int quit() {
  return 0;
}

此实现依赖于call-chaining来实现"事件循环"。我使用引号,因为虽然它在逻辑上是一个事件循环,但是调用堆栈会不断增加并且永远不会展开:

                                            wait_for_query____...
                                           /
                       handle_query_______/
                      /
wait_for_query_______/

虽然它有效,但它总是在堆栈中添加新的堆栈帧,并且最终,在足够的事件之后,它将导致堆栈溢出错误! (哈哈,所以)。

我想要的是这样的

                       handle_query           handle_query
                      /            \         /            \
wait_for_query_______/              \_______/              \_____...

到目前为止我得到了什么

我一直听说操作系统只是一个while(true)循环被中断,所以(因为我的操作系统最近没有出现过SO错误),这就是我的想法会很好:

  • 将main替​​换为:

    while(1)
        if (wait_for_query() == 0) break;
    return 0;
    
  • handle_query更改为1

实际上是否会提高堆叠效率?据我所知,while循环(以及一般循环)仍然使用汇编语言生成堆栈帧(因为它们使用范围/局部变量/等执行所有分支)。

C / C ++中事件循环的最佳实现是什么能够很好地管理调用堆栈

  • 为什么?
  • 基准/比较?
  • 文献/出版物/文档?

注释

这个问题假定一个单线程事件循环。并行化的答案也是可以接受的,但我认为一次性询问所有内容会有点太多;)

消防

2 个答案:

答案 0 :(得分:2)

初始解决方案基本上是已损坏Event loop看起来像这样:

while (q != QUITE) {
  q = wait_for_query();
  handle_query(q);
}

这很简单。这实际上与你所描述的一致:

  

他们是一个简单的概念:等待事件,处理事件,等待更多事件。

在初始代码中,从语义上讲,处理事件handle_query()将永远不会完成,直到所有未来事件也以递归方式完成,这意味着不会完成任何事件。这不是你想要的。

细节可能变得非常复杂,例如你如何得到这些事件?是否阻止?如何发送事件? ......等等。

答案 1 :(得分:0)

实际上,while本身不会生成任何新的堆栈帧。发出call指令时会创建堆栈帧。

如果你提到handle_query返回1,那么你的循环不会让堆栈超过两个级别(wait_query + handle_query)它处理的每个事件:

                                  handle_query           handle_query
                                 /            \         /            \
           wait_for_query_______/              \_______/              \_____...
          /
         /
main_loop

这看起来像你正在寻找的堆栈结构。