【问题标题】:Whats is purpose ftok in Message queues消息队列中的用途 ftok 是什么
【发布时间】:2011-09-09 07:26:34
【问题描述】:

我已经开始阅读 Linux 上 IPC 机制之一的消息队列。但在第一步我有一些非常基本的问题。

  1. 使用ftok()生成唯一ID(key)以及要生成的唯一ID是什么。

  2. 我们不能使用简单的数字来获取我们的密钥,而不是使用ftok()吗?

  3. msget 函数中参数key 的用途是什么?

    #include "sys/msg.h"
    key = ftok("/home/beej/somefile", 'b');
    msqid = msgget(key, 0666 | IPC_CREAT);
    
  4. msqidkey有什么区别?

【问题讨论】:

    标签: c ipc ftok


    【解决方案1】:

    ftok 函数创建一种标识符,用于 System V IPC 函数(semgetshmgetmsgget)。把它想象成一个文件描述符:当你打开一个文件时,你将一个路径传递给open 并得到一个返回的数字,然后用于readwrite 来识别文件。 ftok 函数用于类似目的,但文件描述符的范围仅限于调用 open(及其子进程)的进程,ftok 令牌在整个系统中都有效。

    系统范围的原因是您希望两个或多个独立进程能够访问相同的 IPC 资源。因此,如果您有两个程序,它们都执行key = ftok("/home/beej/somefile", 'b');,它们都将获得相同的令牌,因此可以访问相同的资源(信号量、共享内存、消息队列)。这就是进程间通信的全部意义所在。

    您不能只使用“简单数字”,因为您不知道令牌是否可能是系统内部表的索引等。换句话说,您不知道该令牌在内部是如何使用的,因此您确实需要使用ftok

    手册页说:“指定的路径必须指定调用进程可以访问的现有文件,否则调用将失败。另外,请注意,文件的链接将返回相同的键,给定相同的 id ." 由此,我假设至少有一些ftok 实现通过查找由 path 指定的文件的 inode 号来创建令牌,并将其与第二个参数结合以创建令牌。第二个参数的存在很简单,因此您可以创建一堆 IPC 资源(例如多个信号量来保护不同的资源)。

    至于key_tftok返回的值)和msgget返回的值的区别:前者让你可以访问一堆IPC资源(信号量、共享内存和消息队列),而后者标识一个特定的消息队列。

    【讨论】:

    • 感谢@Drak 的解释,非常有帮助,所以我可以将 key 作为消息队列的名称吗??
    • 我将以更抽象的方式尝试一下,也许这会有所帮助:假设有几个房间。每个房间都有一个可以装信号量的盒子、一个黑板(共享内存)和一个可以装纸(信息)的盒子。现在,key 告诉你去哪个房间。然后使用msgget,您可以在那个房间里拿到带有文件(消息队列)的盒子。然后msgid 只指向那个框,而无需再次输入密钥。
    • 您不知道该令牌在内部是如何使用的,因此您确实需要使用 ftok ftok() 提供绝对零保证返回的 key_t 是独特。如果一个文件系统中可能的文件数和id中使用的8位大于key_t的范围,那么即使对于同一文件系统中的不同文件,结果也不能唯一。并且系统经常安装多个文件系统,因此key_t 冲突的机会更大。 Linux 使用 32 位 key_t,这意味着一旦有超过 1600 万个文件,key_t 值必须重复。
    【解决方案2】:
    1. 我不完全理解您的问题,但它会根据给定的文件路径为系统(而不是进程)生成一个唯一标识符。这个唯一标识符(绑定到路径)允许不同的进程绑定到同一个消息队列。

    2. 是的,你可以,如果他们这样设计的话。但是文件路径是一种更通用的方法,可以实现多个进程可以轻松访问的通用确定性密钥生成机制。

    3. 见 1 和 2

    4. msqid 类似于文件句柄,您可以向该句柄发送和接收消息。关键是允许您将钩子关联到您感兴趣的消息队列中。作为类比,如果关键是全局文件系统中的文件路径,那么 msqid 将是您的进程读取/写入它的句柄.

    【讨论】:

      【解决方案3】:
      1. 什么?

      2. 这可行,但您会选择哪一个?谁保证其他程序(或系统本身)不会使用相同的数字?这会导致混乱。

      3. 目的是提供一个系统范围的唯一值,以识别消息队列。正如手册页所述,

        通常,尽力而为的尝试将给定的 proj_id 字节、inode 编号的低 16 位和设备编号的低 8 位组合成一个 32 位的结果。冲突很容易发生,例如 /dev/hda1 上的文件和 /dev/sda1 上的文件之间。

        所以它只需要一个文件并计算一个 ID,据此可知另一个程序使用相同的文件和项目 ID 将得到相同的结果。

      4. key 只是一个唯一的标识符,但可以用于其他目的,而msqid 是一个真正存在的队列的 ID(句柄类型)。

      【讨论】:

        猜你喜欢
        • 2011-11-13
        • 1970-01-01
        • 1970-01-01
        • 2023-04-03
        • 1970-01-01
        • 2013-08-23
        • 1970-01-01
        • 2014-02-13
        • 2011-06-17
        相关资源
        最近更新 更多