C/C++ 中事件循环的实现在调用堆栈上很好
Implementations for event loop in C/C++ that's nice on the call stack
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
这看起来像您正在寻找的堆栈结构。
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 为什么调用堆栈数组会导致内存泄漏
- 是否可以检查悬挂光纤的调用堆栈?
- MSVC __debugbreak() 与 openGL 错误回调一起使用时不会产生调用堆栈
- 以下代码如何工作以每次为唯一调用堆栈唯一实例化模板函数?
- OpenCV 3 Visual Studio 2017 调试,调用堆栈没有.pdb文件
- C/C++中全局调用堆栈的基础
- 是否可以访问代码中的调用堆栈?
- 调用堆栈显示 SIGBUS,这意味着什么
- 打开C++故障转储不会在调用堆栈中显示正确的行
- 将参数推送到调用堆栈 (C++) 的可移植方法
- 是否可以将功能调用堆栈放在堆上
- 未定义对调用堆栈库的引用出现问题
- 我无法获得由 Clang 构建的优化 NDK 应用程序的调用堆栈
- 调用堆栈中的访问冲突
- GDB正在调试一个缺少特定调用堆栈的符号表的核心转储
- C++按引用传递:如何使用调用堆栈
- 从系统调用内部生成调用堆栈
- 使用 .Net 4.0 时出现堆栈不平衡错误,但在使用 .Net 2.0 时不调用堆栈不平衡错误
- 生成所有可能的调用堆栈的树