Systemm V IPC key是一个整数值,其数据类型是key_t,IPC getd调用将一个key转换成相应的整数IPC标识符,这些调用能够确保如果创建的是一个新的IPC对象,那么对象能够得到一个唯一的标识符,如果指定一个既有对象的key,那么总是会取得该对象的(同样的)标识符(在内部,内核会为各种IPC机制维护着一个数据机构将key映射成标识符)
如下三种方式可以产生唯一的key
- 随机的选取y一个整数作为key值,这些整数值通常会被放在一个头文件中,所有使用IPC对象的程序都需要包含着一个头文件,这个犯法难点在于可能会无意间选取了一个已被另一个应用程序使用的值
- 在创建IPC对象的get调用中将IPC_PRIVATE常量作为key的值,这样就会导致每个调用都会生成一个全新的IPC对象,从而确保每个独享都拥有一个唯一的key
- 使用ftok()函数生成一个(接近唯一)
使用IPC_PRIVATE产生一个唯一的key
id=msgget(IPC_PRIVATE,S_IRUSR|S_IWUSR);
在上面的代码中无需指定IPC_CREATE和IPC_EXCL标记。
这项技术对于父进程在执行fork()之前创建IPC对象,从而导致子进程继承对象标识符的多进程应用是特别有用的,(正常开发嵌入式应用程序一般用不到fork),在客户端–服务端应用程序中也可以使用这项技术,但是客户端必须要通过某种机制获取由服务器创建的标识符(反之亦然),如再创建完一个IPC对象后,服务器可以将这个标识符写入一个将会被客户端读取的文件中。
使用ftok()产生一个唯一的key
ftok()(file to key),函数返回一个合适在后续对某个System V IPC get系统调用进行调用时使用的key值。
#include<sys/ipc.h>
key_t ftok(char *pathname,int proj);
return integer key on success,-1 on failed
key值使用实现定义的算法根据提供的pathname 和proj值生成的。
算法只使用proj的最低的8个有效位应用程序必须要确保pathname引用一个可以应用stat()的既有文件,否则ftok会返回-1
如果引用同一个文件(即i-node)不同的饿路径名(链接)传递给了ftok并且指定了同样的proj值,那么函数必须要返回同样的key值,
换句话说,ftok() 使用i-node 号生成key值,而没有使用文件名来生成key值。由于ftok()函数依赖i-node号,因此在应用程序的生命周期中不应该将文件删除和重新创建,因为重新创建时很可能会生成一个新的i-node号,proj的目的是仅仅从同一个文件中生成多个key.
在linux上,ftok()返回的是一个32位的值,它通过取proj的最低8个有效位,包含该文件所属文件系统的设备的设备号的最低8个有效位以及pathname多引用文件的i-node号的最低16个有效位组合而成。
注:ftok算法与其他UNIX实现所采用的算法类似
,他们都存在一个类似的限制:两个不同的文件可能会产生相同的key值(可能性非常小)。之所以会发生这种情况是因为,不同文件系统上两个文件的i-node号的最低有效位可能相同,并且两个磁盘设备(位于多个磁盘控制器的系统上)可能会拥有同样的次要设备号,但在实践中,不同的应用程序产生同样的key值的可能性非常非常小以至于使用ftok产生key已经是一项非常可靠的技术了
ftok典型用法
key_t key;
int if;
key = ftok("/mydir/file.txt",'x');
if(key == -1)
return -1;
id = msgget(key,IPC_CREAT|S_IRUSR|S_IWUSR);
if(id == -1)
return -1