我已经开始在Linux上读取消息队列中的一种IPC机制。但在第一步,我有一些非常基本的问题。
使用ftok()
生成唯一ID(密钥)以及要生成的唯一ID。
我们不能使用简单的数字来获取我们的密钥而不是使用ftok()
吗?
key
函数中参数msget
的目的是什么?
#include "sys/msg.h"
key = ftok("/home/beej/somefile", 'b');
msqid = msgget(key, 0666 | IPC_CREAT);
msqid
和key
有什么区别?
答案 0 :(得分:21)
ftok
函数创建一种与System V IPC函数(semget
,shmget
,msgget
)一起使用的标识符。您可以将其视为文件描述符:当您打开文件时,您将路径传递给open
并获得一个数字作为回报,然后用于read
和write
来识别文件。 ftok
函数具有类似的用途,但是filedescriptor的范围仅限于调用open
(及其子代)的进程,ftok
标记在整个系统中有效。 / p>
系统范围的原因是您希望两个或更多独立进程可以访问相同的IPC资源。因此,如果你有两个程序,它们都执行key = ftok("/home/beej/somefile", 'b');
,两者都会获得相同的标记,并因此可以访问相同的资源(信号量,共享内存,消息队列)。这就是Inter Process Communication的重点。
您不能只使用“简单数字”,因为您不知道该令牌是否可能是系统内部表的索引或其他内容。换句话说,您不知道该内部如何使用该令牌,因此您需要使用ftok
。
手册页说:“指定的路径必须指定调用进程可访问的现有文件,否则调用将失败。另请注意,在给定相同ID的情况下,指向文件的链接将返回相同的密钥。“由此我假设至少有一些ftok
实现通过查找 path 指定的文件的inode编号来创建令牌,并将其与第二个参数组合到创建令牌。第二个参数只是存在,所以你可以创建一堆IPC资源(比如几个信号量来保护不同的资源)。
至于key_t
(由ftok
返回的值)和由msgget
返回的值的差异:前者允许您访问一堆IPC资源(信号量,共享)内存和消息队列),而后者标识特定的消息队列。
答案 1 :(得分:1)
我不完全理解您的问题,但它会根据给定的文件路径为系统生成唯一的标识符(不是进程)。此唯一标识符(绑定到路径)允许不同的进程绑定到同一个消息队列。
是的,你可以,如果他们这样设计的话。但是文件路径是一种更通用的方式,可以实现多个进程可以轻松访问的通用确定性密钥生成机制。
见1& 2
msqid类似于文件句柄,您可以向该句柄发送和接收消息。关键是允许您将挂钩关联到您感兴趣的消息队列中。作为类比,如果密钥是全局文件系统中的文件路径,那么msqid将是您的进程读/写它的句柄
答案 2 :(得分:0)
什么?
这可行,但你会选择哪一个,谁保证其他程序(或系统本身)不会使用相同的数字?这会导致混淆。
目的是提供系统范围的唯一值,以便识别消息队列。正如联机帮助页所述,
通常,尽力而为尝试将给定的proj_id字节,inode编号的低16位和设备编号的低8位组合成32位结果。可能很容易发生冲突,例如/ dev / hda1上的文件和/ dev / sda1上的文件之间。
所以它只需要一个文件并计算一个ID,从中可以知道使用相同文件和项目ID的另一个程序将获得相同的结果。
key
只是一个唯一但可以用于其他目的的标识符,而msqid
是真正存在的队列的ID(句柄类型)。