我正在开发一种用于在嵌入式Linux进程之间通信的消息队列。我想知道为什么不使用Linux提供的消息队列,比如:
msgctl、msgget、msgrcv和msgsnd。
而是创建共享内存,并与信号量进行同步?
直接在业务嵌入式产品上使用这组函数有什么缺点?
我正在开发一种用于在嵌入式Linux进程之间通信的消息队列。我想知道为什么不使用Linux提供的消息队列,比如:
msgctl、msgget、msgrcv和msgsnd。
而是创建共享内存,并与信号量进行同步?
直接在业务嵌入式产品上使用这组函数有什么缺点?
msgctl()
、msgget()
、msgrcv()
和 msgsnd()
是“System V IPC”消息队列函数。虽然这些函数能够满足您的需求,但它们比较庞大。它们已经被POSIX标准化。
POSIX同样提供了一组更现代的函数,包括mq_close()
、mq_getattr()
、mq_notify()
、mq_open()
、mq_receive()
、mq_send()
、mq_setattr()
和mq_unlink()
,对于您来说可能更好(这真是一个富裕的尴尬)。
但是,您需要检查默认情况下是否在目标平台上安装了其中任何一个。特别是在嵌入式系统中,您可能需要配置它们,甚至需要安装它们,因为它们不是默认安装的(共享内存和信号量也有同样的情况)。
使用这两组消息功能的主要优势在于它们已经经过预调试,因此并发问题已经得到解决 - 而如果您要自己使用共享内存和信号量来实现相同的功能,则需要做大量工作。
因此,尽可能地重复使用。 如果可以选择,使用其中一个消息队列系统而不是重新发明自己的。 如果最终发现存在性能瓶颈或类似问题,则可以调查编写自己的替代方案,但在那之前 — 重用!
System V消息队列(由msg*系统调用操作的那些)有很多奇怪的缺陷和陷阱。对于新代码,我强烈建议使用UNIX域套接字。
话虽如此,我也强烈建议使用消息传递IPC而不是共享内存方案。共享内存更容易出错,并且往往会出现更严重的故障。
消息传递适用于小数据块和需要保持不变性的情况,因为消息队列会复制数据。
共享内存区域在发送/接收时不会复制数据,可以更有效地处理较大的数据集,但编程模型不太干净。
shm
,但不使用sem
进行锁定?您会写入shm
,然后传递IPC消息以宣布数据已准备好? - Gauthierselect()
调用中用于多路复用。在POSIX版本中,除非您有真正迫切的需要使用SYSV队列,否则您甚至可以自动生成线程或信号来处理队列项。最重要的是,它们已经完全调试好了。