提问人:muebau 提问时间:11/15/2023 更新时间:11/16/2023 访问量:105
纯 C++ 设计模式非阻塞 for 循环
pure C++ design pattern non-blocking for loop
问:
我试图阅读我的问题,但甚至找不到合适的词来谷歌它。
假设我在纯 C++ 中有一个这样的函数(将在 ESP32 上运行,没有线程):
void do_something_for_a_long_time(vector a) {
for(int i=0; i < 1000; i++) {
for(int j=0; j < 1000; j++) {
if(a.start == a.end) {
//go deeper
do_something_for_a_long_time(a[1]);
} else {
//end of recursion
//do something with vector
}
}
}
}
问题有点复杂,但主要任务就像上面的代码一样。 我用循环和递归计算一些东西。我必须使用没有线程的纯 C++,因为它将在 Arduino 上运行。
解决这样的事情以获得非阻塞计算的好设计模式是什么:
loop() {
//call this often
do_something_non_blocking(...);
//other stuff
}
我的意思是,如果调用非阻塞函数,我想做下一步,并且会非常非常频繁地调用该函数,而不是调用一次并获得结果(并阻止所有内容)。 我可以创建一些复杂的状态机,但想找到一个通用的干净解决方案。如果出现这样的问题,部分原因是为了更好地设计。
想法:
- 拆分 for 循环
- 初始化
- 身体
- 退出
- 编写宏库以将代码封装在状态机中
答:
0赞
A.N
11/16/2023
#1
你可以做类似的事情,它以一种创造性的(而且老实说很可怕)的方式利用 C switch 语句来实现协程,在这种情况下,他使用静态变量,这通常可能不是一个好主意,但我认为它也适用于你的用例。
评论
0赞
muebau
11/16/2023
谢谢。我会读到的。它是完美的,因为它从C预处理器一直到C++20原生到一般哲学。再次感谢你。
1赞
Useless
11/16/2023
#2
您正在寻找的一般概念是协程或协作多任务处理。
这个想法是可以暂停和恢复功能,以便可以在单个线程上交错多个活动。
它是“协作的”,因为函数需要显式产生(例如,使用 或 ),而不是像线程那样被调度器抢占。co_yield
co_await
你总是可以编写某种状态机来手动执行此操作,就像我们可以编写 functor 类来手动存储其状态一样,然后我们才拥有具有一流语言支持的 lambda。
铌。对于您的特定用例,状态机需要以某种方式将您的搜索空间分解为离散的块(可接受的持续时间),然后每个“步骤”只处理一个块。如果你能做到这一点,这样即使你没有时间找到最好的动作,你也能得到一个相当好的结果,那就更好了。
评论
0赞
muebau
11/16/2023
好的,这是值得阅读和学习的东西。非常感谢。我也对状态机和块有想法。这将很棒,因为会有一个“足够好”的选择。
评论
fork
if(a.start == a.end) { do_something_for_a_long_time(a[1]);
毫无意义。为了一个最小的例子而使你的代码更简单是好的,但这不是“最小的”,它只是没有意义perform_one_step
co_await