【问题标题】:Why message queues are in Kernel address space but not the shared memory为什么消息队列在内核地址空间而不是共享内存
【发布时间】:2014-06-24 11:18:32
【问题描述】:

我在一次采访中被问到为什么消息队列在内核地址空间中,并且在下面的链接中也有同样的建议。

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

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

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

我不确定这是正确的答案。

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

我真的想不通为什么会这样。

谁能解决这两个问题?

【问题讨论】:

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


    【解决方案1】:

    我会说消息队列在内核空间中维护是出于 (a) 历史原因和 (b) 架构原因——它们被建模为内核管理的资源:它们仅根据定义的定义创建、修改和删除API。这意味着,例如,一旦一个进程发送了一条消息,它就不能在飞行中被修改,它只能被接收。访问控制也施加在队列中的对象上。如果 API 保存在用户空间内存中,管理和执行 API 的细节会很困难。

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

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

    【讨论】:

    • 感谢 Gil 的回答,我能够理解你关于共享内存的观点,但我仍然不明白你关于消息队列的观点,为什么在用户空间维护消息队列很困难?您是否认为我的理由是内核逻辑地址不能被换出,从而使消息队列更加健壮?
    • 在用户空间创建消息队列一点也不难,但要让它们遵循定义的所有权和访问控制语义。请注意,新创建的消息队列归创建进程的 EUID 所有,并且权限与其相关联。在用户空间中提供和执行这些权限会很困难。我看不出不被换出如何使队列更加健壮(尽管它可能具有性能优势)。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-19
      • 2011-06-30
      • 2011-07-26
      • 2012-06-11
      • 2014-11-13
      • 1970-01-01
      • 1970-01-01
      • 2012-03-02
      相关资源
      最近更新 更多