我正在用C语言开发一个相当复杂的微控制器应用程序,我对如何在不同的任务/线程之间“链接”我的共享数据而不耦合它们有一些疑问。
到目前为止,我已经使用时间片调度程序来运行我的应用程序,因此不需要数据保护。但我想让应用程序正常运行,我想让它为以后的多线程操作系统做好准备。
我试着用一个完全不同的系统来简化我的问题。我无法添加图片,因为我是新用户,但我将尝试解释:
我们得到了4个任务/线程:3个输入线程,通过硬件抽象层(HAL)从不同的传感器读取一些传感器数据。收集的传感器数据存储在任务域中(即:它们不是全局的!!).
现在我们还有一个输出任务,我们称之为“调节器”。调节器必须使用(读取)从所有3个传感器收集的传感器数据,以产生正确的输出。
问题:监管者如何在不与其他任务耦合的情况下读取存储在不同输入任务中的数据?
调节器必须只通过引用知道输入任务及其数据(即:不包括,不耦合)。
到目前为止,调节器已经有一个指向每个所需传感器数据的指针,该指针是在初始化时设置的。由于数据保护,这在多线程应用程序中不起作用。
我可以为每个传感器值创建一些利用信号量的getSensorValue()函数,然后用函数指针将它们链接到调节器。但这会占用很多记忆!!有更优雅的方法吗?我只是在寻找输入。
我希望这一切都是可以理解的:)

最佳答案

从您在问题和评论中描述的内容来看,您似乎最担心的是传感器和调节器之间的接口内存不足,实现细节很少,而且不知道每个传感器实现的明确细节。
由于您在C中,并且没有一些C++类特性,可以通过继承更容易封装,所以我建议您从每个传感器线程中生成一个公共数据包,该数据线程传递给监管者,而不是传递函数指针。形式的结构

struct SensorDataWrap {
    DataType *data;
    LockType *lock;
    ... other attributes such as newData or sensorName ...
};

可以让你把数据传递给监管机构,在那里你可以在阅读之前锁定数据。同样,传感器在写入之前也需要锁定。如果将数据更改为双指针,则可以使write命令只需锁定交换底层指针所需的时间。然后,调节器只需要每个线程中的一个SensorDataWrap结构来处理该线程的信息,而不必考虑传感器的实现细节。
LockType可以是一个信号量,也可以是任何支持单次访问获取的高级锁对象。任何此类锁的内存占用应该只有几个字节。此外,这里不需要复制数据,因此相对于传感器读取,不应该对内存大小产生任何乘法影响。您正在使用的硬件应该有足够的空间来保存您所描述的传感器的数据的单个副本,以及足够的闪存空间来容纳信号量或锁定对象。
通信的实现细节现在仅限于锁定、执行操作、解锁,并且不需要复杂的功能指针或特定于传感器的报头包括。它应该接近任何线程共享数据程序所需的最小逻辑。该程序也应该可以在没有重大变化的情况下转移到其他微控制器上——这种通信只会受到线程和锁的压力/缺失的真正限制。
另一个选项是传递一个三缓冲区对象并执行缓冲区翻转,以避免信号量和锁。这种方法需要创建原子整数/bool支持(如果有信号量,编译器很可能已经公开了这种支持)。在this blog上可以找到使用三重缓冲区进行并发的指南。这种方法将使用更多的活动内存,但是是避免大多数并发问题的一种非常巧妙的方法。

关于c - 如何在不耦合任务/线程的情况下共享数据?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15793860/

10-11 19:45
查看更多