gpt4 book ai didi

c++ - 使用回调函数打破 while 循环的最佳方法是什么?

转载 作者:太空宇宙 更新时间:2023-11-04 02:33:07 27 4
gpt4 key购买 nike

虽然我使用的是 Arduino IDE,但运行代码的设备是 ESP8266。

我确定我的代码结构有误,但我不确定最好的方法,希望有人能给我指出正确的方向。

为了归结这个场景,我必须举一个基本的例子:

我的主循环 () 函数只是在每次传递时运行一个回调 () 函数 (PubSubClient MQTT)。此回调函数首先将全局 bool 变量“run”设置为 false,然后将执行以下 3 项操作中的一项:

  1. 如果收到“1”,它将运行一个名为 action1() 的函数。
  2. 如果收到“2”,它将运行一个名为 action2() 的函数。
  3. 如果接收到“3”,它将向 Serial 打印一行。
  4. 如果收到任何其他内容或未收到任何内容,它将不执行任何操作。

action1() 和 action2() 函数都是循环,看起来像这样:

void action1() {
run = true; // Do this once to start the loop
while (run == true) {
// Do some stuff
callback(); // To check for new messages
}
}

问题是:

如果 action1() 正在运行并且 callback() 接收到“3”,则一切正常。回调会将“run”变量设置为 false,将行打印到 Serial,然后返回到 action1() 循环,这将中断并且整个循环返回到 loop()。

但是如果 action1() 正在运行并且 callback() 收到启动 action2() 的命令,action2() 将启动并且 action1() 只是暂停等待返回。

因此,我认为在 action1() 和 action2() 之间来回切换可能会导致内存问题,因为循环会相互堆叠。如果我这样做足够多,我会看到设备崩溃。

我认为 callback() 可能需要“排队”action1() 或 action2(),然后让主循环() 运行它们?这样我们总是会回到主循环()从而结束所有其他循环。不过,我确信有更好的解决方案。

最佳答案

你的代码结构确实不正确:

  • 对回调的调用将会堆积起来。如果您有很多回调事件,您可能会以堆栈溢出而告终。
  • 使用全局run 变量使callback() 不可重入,这可能会导致处理过早结束。

事实上,您最好选择事件循环,正如您已经指出的那样,它基于队列:

  • callback() 只有在收到 ai item item 时才会被调用,它会将 item 排队并返回。
  • 您的主循环会在每次迭代时从队列中读取可用的内容,然后调用正确的操作。
  • 如果需要,您也可以调用一些轮询函数。
  • 如有必要,您还可以调用输出函数来反射(reflect)当前状态。

目前尚不清楚主循环是否会永远运行,或者只运行到收到一些特殊输入,或者直到队列为空。由您决定。

我不知道你的回调在arduino模型中是如何触发的。但是,如果它中断了正在运行的进程,您还需要确保队列中没有竞争条件,例如使用锁。

关于c++ - 使用回调函数打破 while 循环的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40834667/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com