system V IPC key最详细教程
在使用System V IPC时,无论调用shmget()、semget()、msgget()哪一个函数,它的第一个参数都是key_t key
,这个key可以被转换成IPC的标识符,每一个标识符都代表唯一一个IPC,那么如何生成唯一的标识符呢?最常用的有两种做法!
-
IPC_PRIVATE:
- 在使用get创建IPC对象时,使用IPC_PRIVATE宏作为key的值,这样每次调用get都会生成一个全新的对象。
- 但是生成的IPC键值都是相同的了0x00000000,不能使用ipcrm根据键值来删除了,其它删除方式不受影响。
- 使用IPC_PRIVATE时,创建IPC时flg标志位无需指定IPC_CREAT和IPC_EXCL标记,直接给权限就好
- 使用IPC_PRIVATE后,由于每次调用都会生成一个新的IPC,所以使用这个方式生成的IPC只能用于具有亲缘间的进程进行通信!
-
ftok()函数(file to key):
-
函数原型
key_t ftok(const char *pathname, int proj_id);
-
该函数通过文件或路径(必须真实存在,否则ftok返回-1)与用户指定的proj_id生成近乎唯一的key值
- 如果pathname是不同路径下的相同文件(位置相同),那么也会生成一个相同的key值,因为ftok()是根据文件的
i-node
号生成key的,可以通过stat + 文件名查看文件的i-node,或者ls -i查看 - proj_id的作用纯属就是为了使用同一个文件多生成几个key值,最多一个文件可以生成256个key,不过需要注意的是,尽量不要将proj_id设置为0,虽然Linux上是允许的,但是在可移植的应用程序上使用不是一个好的做法,因为在其它某些系统上,如AIX5.1(IBM类UNIX)上,当该值为0时,ftok会返回-1。
- 如果pathname是不同路径下的相同文件(位置相同),那么也会生成一个相同的key值,因为ftok()是根据文件的
-
在Linux系统上,ftok返回一个32位的值,它通过proj_id参数的最低8个有效位、该文件所属文件系统的设备的设备号的最低8个有效位及pathname所引用文件的i-node号的最低16个有效位组合而成。(文件设备号也可以使用stat()函数或stat命令获取查看)
-
参数proj_id只取最低8位,所以决定了它的真实有效值范围0-255(当然填超过255的值也行,但是只取最低8位)
-
例如:
key_t key = ftok("../file", 1); printf("key = %d\n", key); 输出结果: key = 16863526
首先参数2的值是1,那么低8位是:0000 0001;文件系统设备号经查看是2049,那么最低8位是:0000 0001;文件i-node号是282918,最低有效16位是:0101 0001 0010 0110;最后组合在一起的二进制是:0000 0001 0000 0001 0101 0001 0010 0110,转换成十进制是:16863526
-
-
ftok生成key的算法上面讲完了,根据这个算法应该知道一个限制就是,两个不同的文件可能会产生相同key值(有概率,但是概率极小),因为两个不同文件的i-node值的最低16位有概率是相同的。假如恰巧相同,还必须要有相同的设备号,相同的proj_id,才会生成一个相同的key。目前在编程中,ftok还是属于可靠生成key的方式,广泛应用于生产当中!毕竟产生相同key的概率差不多等于你在马路边捡到一张彩票,这张彩票还中了500w的概率!
-