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

Implementations for event loop in C/C++ that's nice on the call stack

本文关键字:调用 堆栈 很好 实现 C++ 事件 循环      更新时间:2023-10-16

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;
}

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

                                            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++ 中能够很好地管理调用堆栈的事件循环的最佳实现是什么?

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

笔记

此问题假定为单线程事件循环。并行化答案也是可以接受的,但我认为一下子问起来会有点多;)

火走

最初的解决方案从根本上被打破了。事件循环如下所示:

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

就这么简单。这实际上与您描述的内容一致:

它们很简单:等待事件,处理事件,等待更多事件。

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

细节可能会变得非常复杂,例如你如何获得事件?它是否阻止?如何调度事件?等。

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

如果您如前所述返回handle_query 1,那么您的循环不会为它处理的每个事件将堆栈进一步增长到两个级别(wait_query + handle_query(:

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

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