15

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

  1. 用于ftok()生成唯一 ID(密钥)以及要生成的唯一 ID 是什么。

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

  3. key函数中参数的目的是什么msget

    #include "sys/msg.h"
    key = ftok("/home/beej/somefile", 'b');
    msqid = msgget(key, 0666 | IPC_CREAT);
    
  4. msqid和 和有什么不一样key

4

3 回答 3

34

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

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

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

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

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

于 2011-09-09T07:44:20.210 回答
1
  1. 我不完全理解您的问题,但它会根据给定的文件路径为系统(而不是进程)生成一个唯一标识符。这个唯一标识符(绑定到路径)允许不同的进程绑定到同一个消息队列。

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

  3. 见 1 和 2

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

于 2011-09-09T07:45:59.497 回答
-1
  1. 什么?

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

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

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

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

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

于 2011-09-09T07:41:54.927 回答