如何在任务/线程之间共享数据而不耦合它们?

时间:2013-04-03 17:15:53

标签: c microcontroller shared coupling

我正在 C 开发一个相当复杂的微控制器应用程序,我对如何在不耦合它们的情况下在不同任务/线程之间“链接”我的共享数据有一些疑问。

到目前为止,我已经使用时间分片调度程序来运行我的应用程序,因此不需要数据保护。但是我想让应用程序正确,我希望以后为多线程操作系统做好准备。

我试图通过使用与我正在处理的实际系统完全不同的系统来简化我的问题。我无法添加图片,因为我是一个新用户,但是请尝试解释:

我们有4个任务/线程:3个输入线程,通过硬件抽象层(HAL)从不同的传感器读取一些传感器数据。收集的传感器数据存储在任务域中(即:它们不是全局的!!)。 现在我们还有1个输出任务,我们称之为“Regulator”。调节器必须使用(读取)从所有3个传感器收集的传感器数据,以产生适当的输出。

问题:监管机构如何在不与其他任务耦合的情况下读取存储在不同输入任务中的收集数据?

监管机构必须仅通过参考了解输入任务及其数据(即:没有#includes,没有耦合)。

到目前为止,Regulator已经有一个指向每个所需传感器数据的指针,并且该指针在初始化时设置。由于数据保护,这在多线程应用程序中不起作用。

我可以为每个传感器值制作一些使用信号量的getSensorValue()函数,然后使用函数指针将它们链接到Regulator。但这会占用大量内存!有更优雅的方式吗?我只是在寻找投入。

我希望这一切都可以理解:)

1 个答案:

答案 0 :(得分:2)

根据您在问题和评论中的描述,您似乎最担心传感器和监管机构之间的接口是低内存,具有最少的实施细节,而且不知道每个传感器实施的明确细节。

由于您使用的是C并且没有一些C ++类功能可以通过继承使封装更容易,我建议您从每个传感器线程中传递一个公共数据包,然后传递给Regulators而不是传递给功能指针。形式的结构

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

允许您将数据传递给Regulators,您可以在阅读之前锁定。同样,传感器在写入之前需要锁定。如果您将数据更改为双指针DataType **data,则可以使写入命令仅需要锁定交换底层指针所需的时间。然后,调节器只需要来自每个线程的单个SensorDataWrap结构来处理该线程的信息,而不管传感器的实现细节如何。

LockType可以是信号量,也可以是任何更高级别的锁定对象,它可以实现单一访问。任何此类锁的内存占用量应仅为几个字节。此外,您不会在此处复制数据,因此相对于传感器读数,您不应对内存大小产生任何乘法效应。您正在使用的硬件应该有足够的空间来容纳来自您描述的传感器的单个数据副本,以及足够的闪存空间以容纳信号量或锁定对象。

现在,通信的实现细节仅限于锁定,操作,解锁以及不需要复杂的函数指针或SensorN特定的头部包含。它应该接近任何线程共享数据程序所需的最小逻辑。该程序还应该可以转移到其他微控制器而不会发生重大变化 - 通信只受到线程和锁的存在/不存在的限制。

另一种选择是传递三重缓冲区对象并进行缓冲区翻转以避免信号量和锁定。这种方法需要创建原子整数/布尔支持(如果你有信号量,你很可能已经由编译器公开)。可以在this blog上找到使用三重缓冲区进行并发的指南。这种方法将使用更多的活动内存,但它是一种非常灵活的方法,可以避免大多数并发问题。