为什么消息队列在内核地址空间中而不在共享内存中

时间:2014-05-07 12:57:17

标签: linux-kernel linux-device-driver message-queue shared-memory

我在接受采访时被问到为什么消息队列在内核地址空间中,并且在以下链接中提出了相同的建议。

http://stork.sourceforge.net/thesis/node49.html

其中说“消息队列最好被描述为内核寻址空间内的内部链表”。

我回答告诉面试官内核逻辑地址无法换出,因此在我们必须在任何进程崩溃后从消息队列中检索一些数据的情况下,使消息队列更加健壮。

我不确定这是正确答案。

然后面试官问为什么共享内存不是内核地址空间的一部分?

我真的不能想到它为什么会这样。

有人可以解决这两个问题吗?

2 个答案:

答案 0 :(得分:2)

我会说消息队列在内核空间中维护(a)历史原因和(b)架构原因 - 它们被建模为内核管理的资源:它们只根据定义创建,修改和删除API。这意味着,例如,一旦进程发送消息,就不能在飞行中修改它,它只能被接收。访问控制也强加于队列中的对象。如果将API维护在用户空间内存中,则难以管理和实施API的详细信息。

话虽如此,除了安全/保证方面,您可能实际上可以使用共享内存区域实现具有相同API 的消息队列,并使其对于使用应用程序完全透明。

对于共享内存本身,关键是它是共享。这意味着为了实现其功能,必须同时在进程A和进程B的虚拟地址空间中访问它。如果进程A在共享存储器中的给定偏移量处存储一个字节,则进程B应该(理想地)近乎即时地看到该修改(尽管在多处理器系统中显然总是存在高速缓存延迟的可能性等)。并且永远不允许用户空间进程直接修改内核虚拟地址,因此必须在用户虚拟地址空间中创建共享映射(尽管内核无法 将同一区域映射到内核虚拟中地址空间)。

答案 1 :(得分:0)

与共享内存不同,可以在内核空间中实现消息队列是因为在两个用户进程之间传输数据时,队列中每个元素的内容只是用户空间和内核地址空间之间的COPY操作。因此,用户不可能通过内存指针破坏内核内存空间。类似于Linux使用copy_to_user()和copy_from_user()保护内核免受用户粗心大意。