C 设计模式在不阻塞的情况下执行一系列操作?

C design pattern performing a list of actions without blocking?

嵌入式 C。我有一个我想做的事情的列表,在程序上,主要是 READ 和 WRITE 以及 MODIFY 操作,作用于最后一条语句的结果。它们每个最多需要 2 秒,我无法阻止。

每个动作都可以有 COMPLETE 和 ERROR 状态,其中有错误发生原因的子状态。或者在比赛中我会想检查或修改一些数据。

每个动作列表都是一个大开关,为了重新进入,我保留了我正在进行的步骤的列表,一个成功的步骤++,下次我会回到列表的下方。

很简单,但我发现为了不阻塞,我花费了大量精力不断检查状态、错误和边缘。一遍又一遍。

我会说我 80% 的代码只是检查和移动系统。必须有更好的方法!

是否有任何异步设计模式可以有效地处理一些 exception/edge/handling?

编辑:我知道如何使用回调,但并不真正将其视为“解决方案”,因为我只需要返回到同一列表的不同部分以进行下一步操作。也许了解其他语言的异步和等待如何工作的后端会有所帮助?

Edit2:我确实有一个用于其他项目的实时操作系统,但这个具体问题,假设没有 threads/tasks,只是裸机超级循环。

你的困境非常适合状态机(真的,可能 UML statecharts)。每个不同的请求都可以在其自己的状态机中处理,状态机以非阻塞的方式处理事件(例如 COMPLETEERROR 指示), 运行-对-完成方式。随着事件的到来,请求的状态机通过其不同的状态走向完成。

对于嵌入式系统,我经常在这种情况下使用QP event-driven framework。事实上,当我查找此 link 时,我注意到第一段使用了术语 "non-blocking"。该框架提供的不仅仅是具有层次结构的状态机(状态中的状态),这已经非常强大了。

该站点还提供了一些有关解决您的特定问题的方法的有用信息。我建议从网站的 Key Concepts 页面开始。

为了让您体验内容及其与您的困境的相关性:

In spite of the fundamental event-driven nature, most embedded systems are traditionally programmed in a sequential manner, where a program hard-codes the expected sequence of events by waiting for the specific events in various places in the execution path. This explicit waiting for events is implemented either by busy-polling or blocking on a time-delay, etc.

The sequential paradigm works well for sequential problems, where the expected sequence of events can be hard-coded in the sequential code. Trouble is that most real-life systems are not sequential, meaning that the system must handle many equally valid event sequences. The fundamental problem is that while a sequential program is waiting for one kind of event (e.g., timeout event after a time delay) it is not doing anything else and is not responsive to other events (e.g., a button press).

For this and other reasons, experts in concurrent programming have learned to be very careful with various blocking mechanisms of an RTOS, because they often lead to programs that are unresponsive, difficult to reason about, and unsafe. Instead, experts recommend [...] event-driven programming.

你也可以自己做状态机而不使用像 QP 这样的事件驱动框架,但你最终会重新发明轮子 IMO。