首页 > 代码库 > 信号量,消息队列,共享内存中ket_t键值的生成函数ftok。
信号量,消息队列,共享内存中ket_t键值的生成函数ftok。
在System V中,我们经常用用key_t的值来创建或者打开信号量,共享内存和消息队列。这个在IPC的环境中十分的重要,比如说,服务器创建了一个消息队列,等待 客户机发送请求。那么如何创建或者打开已有的消息队列呢?一般而言,我们对于服务器使用的路径和项目id(proj_id)是已知的,所以客户机可以获取 相同的key来打开 消息队列并进行操作。下面就是ftok的使用原型:
ftok函数
函数ftok把一个已存在的路径名和一个整数标识得转换成一个key_t值,称为IPC键:
# include
# include
key_t ftok(const char *pathname, int proj_id);
DESCRIPTION
The ftok function uses the identity of the file named by the given pathname (which must refer to an existing, accessible file) and the least significant 8 bits of proj_id (which must be nonzero) to generate a key_t type System V IPC key。
该函数把从pathname导出的信息与id的低序8位组合成一个整数IPC键。
# include <sys/types.h>
# include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);
注意:
1)pathname一定要在系统中存在
2)pathname一定是使用进程能够访问的
3)proj_id是一个1-255之间的一个整数值,典型的值是一个ASCII值。
当成功执行的时候,一个key_t值将会被返回,否则-1被返回。
下面的程序简单的演示和打印如何使用ftok及其对应值
#include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> int main( void ) { for ( int i = 1; i < 256; ++ i ) printf( "key = %ul/n", ftok( "/tmp", i ) ); return 0; }
注意:
<span style="background-color: rgb(255, 255, 255);">#include <stdio.h> #include <sys/ipc.h> void main(int argc, char* argv[]) { if (argc !=2 ) { printf("Usage: %s KeyFile/n e.g. %s /tmp/mykeyfile/n", argv[0], argv[0]); return; } printf("Key generated by ftok: 0x%x/n", ftok(argv[1], 1)); } </span>
# ./test01 /tmp/mykeyfile
Key generated by ftok: 0x101000b
Key generated by ftok: 0x1010017
可以看到,虽然文件名称都是 /tmp/mykeyfile,并未改变,但由于中间发生了文件删除并重新创建的操作,前后两次所得到的键值已经不再相同。避免此类问题最根本的方法,就是采取措施保证pathname所指定的文件(或目录)在共享内存的使用期间不被删除,不要使用有可能被删除的文件;或者干脆直接指定键值,而不借助ftok来获取键值。
关于ftok函数的几个疑问
系统建立IPC通讯(如消息队列、共享内存时)必须指定一个ID值。通常情况下,该id值通过ftok函数得到。 ftok原型如下: key_t ftok( char * fname, int id ) fname就时你指定的文件名,id是子序号。 在一般的UNIX实现中,是将文件的索引节点号取出,前面加上子序号得到key_t的返回值。 如指定文件的索引节点号为65538,换算成16进制为0x010002,而你指定的ID值为38,换算成16进制为0x26,则最后的key_t返回值为0x26010002。 查询文件索引节点号的方法是: ls -i 当删除重建文件后,索引节点号由操作系统根据当时文件系统的使用情况分配,因此与原来不同,所以得到的索引节点号也不同。 如果要确保key_t值不变,要目确保ftok的文件不被删除,要么不用ftok,指定一个固定的key_t值。 另外说一句:在aix等操作系统上,有多个文件系统,会出现分布在不同的文件系统上的两个文件具有相同的索引节点号,此时用ftok对这两个文件进行操作,只要id参数不变,得到的key_t值相同,造成创建消息队列失败。不过这种情况相当少见罢了。 |
信号量,消息队列,共享内存中ket_t键值的生成函数ftok。