纯 C++ 设计模式非阻塞 for 循环

pure C++ design pattern non-blocking for loop

提问人:muebau 提问时间:11/15/2023 更新时间:11/16/2023 访问量:105

问:

我试图阅读我的问题,但甚至找不到合适的词来谷歌它。

假设我在纯 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 循环
    • 初始化
    • 身体
    • 退出
  • 编写宏库以将代码封装在状态机中
C++ for 循环 非阻塞

评论

1赞 NathanOliver 11/15/2023
听起来你正在寻找或等价物。fork
0赞 463035818_is_not_an_ai 11/15/2023
if(a.start == a.end) { do_something_for_a_long_time(a[1]);毫无意义。为了一个最小的例子而使你的代码更简单是好的,但这不是“最小的”,它只是没有意义
1赞 463035818_is_not_an_ai 11/15/2023
你不需要一个复杂的状态机,你只需要把它封装在一个有方法的类中perform_one_step
0赞 Red.Wave 11/15/2023
在这种情况下,“阻塞”一词的含义是什么?阻塞通常意味着等待另一段并发代码到达某个点。
1赞 pptaszni 11/15/2023
您可以使用一个经常调用的协程来“不阻塞”。如果可以在 ESP32 上安装 C++20。co_await

答:

0赞 A.N 11/16/2023 #1

你可以做类似的事情,它以一种创造性的(而且老实说很可怕)的方式利用 C switch 语句来实现协程,在这种情况下,他使用静态变量,这通常可能不是一个好主意,但我认为它也适用于你的用例。

评论

0赞 muebau 11/16/2023
谢谢。我会读到的。它是完美的,因为它从C预处理器一直到C++20原生到一般哲学。再次感谢你。
1赞 Useless 11/16/2023 #2

您正在寻找的一般概念是协程协作多任务处理

这个想法是可以暂停和恢复功能,以便可以在单个线程上交错多个活动。

它是“协作的”,因为函数需要显式产生(例如,使用 或 ),而不是像线程那样被调度器抢占。co_yieldco_await

你总是可以编写某种状态机来手动执行此操作,就像我们可以编写 functor 类来手动存储其状态一样,然后我们才拥有具有一流语言支持的 lambda。

铌。对于您的特定用例,状态机需要以某种方式将您的搜索空间分解为离散的块(可接受的持续时间),然后每个“步骤”只处理一个块。如果你能做到这一点,这样即使你没有时间找到最好的动作,你也能得到一个相当好的结果,那就更好了。

评论

0赞 muebau 11/16/2023
好的,这是值得阅读和学习的东西。非常感谢。我也对状态机和块有想法。这将很棒,因为会有一个“足够好”的选择。