0

我正在编写一个具有多个多线程进程的稍微复杂的软件。因为在其中一个中我需要实时功能(基本上是为了健壮性),所以我为 Xenomai 修补了我的目标内核并使用 Xenomai 的本机皮肤对其进行了编程。

现在我需要沟通两个进程:一个运行实时任务,另一个运行简单的pthreads(后者在没有 Xenomai 的实时库/皮肤的情况下编译)。

我的问题是:我能以某种方式与他们交流吗?例如,我可以创建一个共享内存对象 ( shm_open) 并共享互斥锁,即使其中一个在 RT 环境中?

  • 如果答案是肯定的,我应该在 Xenomai 中使用 POSIX 皮肤吗?
  • 如果答案是否定的,我如何安全地共享数据/通信它们?命名管道是我能想到的唯一方法......
4

1 回答 1

2

我建议你使用 Xenomai 原生 API 来创建命名管道,诸如此类rt_pipe_create()

您还可以使用另一件事:消息队列。但是我一直选择命名管道而不是消息队列。

共享内存和消息队列都可以用来在进程之间交换信息。不同之处在于它们的使用方式。

共享内存正是您所想的:它是一个可以被多个进程读写的存储区域。它不提供固有的同步;换句话说,由程序员来确保一个进程不会破坏另一个进程的数据。但它在吞吐量方面是有效的:读取和写入是相对快速的操作。

消息队列是单向管道:一个进程写入队列,另一个进程按照写入顺序读取数据,直到出现数据结束条件。创建队列时,会设置消息大小(每条消息的字节数,通常相当小)和队列长度(待处理消息的最大数量)。访问比共享内存慢,因为每个读/写操作通常是一条消息。但是队列保证每个操作要么成功处理整条消息,要么在不改变队列的情况下失败。因此,作者在只写了部分消息后永远不会失败,而读者要么会检索到完整的消息,要么什么都不会。

本质上,管道——无论是命名的还是匿名的——都像消息传递一样使用。有人向接收者发送一条信息,接收者可以接收到它。共享内存更像是发布数据——有人将数据放在共享内存中,而读者(可能很多)必须使用同步,例如通过信号量来了解有新数据的事实,并且必须知道如何读取内存区域以查找信息.

使用管道,同步很简单,并且内置于管道机制本身 - 当有趣的事情发生时,您的读取和写入将冻结和解冻应用程序。使用共享内存,可以更轻松地进行异步工作,并且只偶尔检查一次新数据——但代价是更复杂的代码。另外,您可以进行多对多通信,但这需要再次进行更多工作。此外,由于上述原因,调试基于管道的通信比调试共享内存更容易。

一个小的区别是fifos在文件系统中直接可见,而共享内存区域需要像ipcs这样的特殊工具来管理它们,以防你创建一个共享内存段但你的应用程序死了并且没有自行清理(同样适用信号量和许多其他您可能需要与共享内存一起使用的同步机制)。

共享内存还可以让您更好地控制缓冲和资源使用 - 在操作系统允许的限制范围内,由您决定分配多少内存以及如何使用它。使用管道,操作系统会自动控制事物,因此您再次失去了一些灵活性,但可以减轻很多工作。

最重要的几点总结:一对一通信的管道,更少的编码和让操作系统处理事情,多对多的共享内存,更多的手动控制,但代价是更多的工作和更难的调试

于 2013-11-13T06:53:16.913 回答