ftok key值冲突

前两天遇到的关于ftok()函数的问题,当时发了帖子求助,解决后整理于此!

帖子在这儿:ftok产生的key冲突了

最近遇到一个问题,在用户b下创建共享内存失败,跟踪代码发现shmget的errno为17(要创建的这个共享内存已经存在了),可是在该用户下通过ipcs查看确实没有共享内存啊,后来发现,用户a下已经创建的共享内存与用户b要创建的共享内存冲突了,准确的说是key值冲突了,key值是通过ftok函数生成的。


上网查询了一个,ftok是根据文件i节点和调用ftok时的id值产生的,而且还给出了例子加以说明,如下:
在一般的UNIX实现中,是将文件的索引节点号取出,前面加上子序号得到key_t的返回值。如指定文件的索引节点号为65538,
换算成16进制为 0x010002,而你指定的ID值为38,换算成16进制为0x26,则最后的key_t返回值为0x26010002。

b用户下有目录trnlog,通过ls -i命令查看tt的i节点为 2228246
ftok 得到的key值为 16908310  <==>  0x1020016

a用户下有文件comm,通过ls -i命令查看xx的i节点为 2097174
ftok 得到的key值为 16908310  <==>  0x1020016

问题来了:
1)两个用户下的文件i节点不同,通过ftok函数得到的key值是相同的,为什么呢?
2)用户a创建的共享内存对其他用户有影响吗?也就是说进程创建共享内存的时候系统会全系统检查该key值有没有创建过共享内存?

小弟恳请大神点拨说明,感谢万分!


用户a和b 文件i节点及程序调试查看ftok产生的key值如下
用户a:

C/C++ code
?
1
2
a-/home/a/etc/ipckey>ls -li
2097174 -rwxrw-r--. 1 a a    0 Sep 22  2013 comm

程序调试:
C/C++ code
?
1
2
3
4
5
6
7
64         sprintf (strPath, "%s/etc/ipckey/comm" , getenv ( "HOME" ));
(gdb) p strPath
$1 =  "/home/a/etc/ipckey/comm" '\000'  <repeats 91 times>
(gdb) n
67         if  ((ilShareKey = ftok(strPath,1)) == (key_t)-1)
(gdb) p ilShareKey
$2 = 16908310


用户b:
C/C++ code
?
1
2
b-/home/b/etc/ipckey>ls -li
2228246 drwxr-xr-x. 2 b b 4096 Sep 22  2013 trnlog

程序调试:
C/C++ code
?
1
2
3
4
5
6
7
64         sprintf (strPath, "%s/etc/ipckey/trnlog" , getenv ( "HOME" ));
(gdb) p strPath
$1 =  "/home/b/etc/ipckey/trnlog" '\000'  <repeats 89 times>
(gdb) n
67         if  ((ilShareKey = ftok(strPath,1)) == (key_t)-1)
(gdb) p ilShareKey
$2 = 16908310
好吧,没人解答我来说说吧!
翻看了ftok的实现源码,得知ftok就是通过文件的一些属性加上id值得到的key值,的确存在不同文件同一id值生成相同key值的可以,比如我遇到的这种情况。
先列出ftok的实现,精简如下:
C/C++ code
?
1
key = ((st.st_ino & 0xffff) | ((st.st_dev & 0xff) << 16) | ((proj_id & 0xff) << 24));

用户a:
C/C++ code
?
1
2
a-/home/a/etc/ipckey>stat -c  "%i %d"  comm
2097174 64770

用户b:
C/C++ code
?
1
2
b-/home/b/etc/ipckey>stat -c  "%i %d"  trnlog
2228246 64770


按照ftok的实现经过计算,的确得出相同的结果。
所以说,ftok的使用不只是大家所说的,如果生成key值的文件在使用,不允许删除重建,否则会出现意想不到的问题;而且,相同的机器,我们也需要注意我遇到的这种情况。

通过以上,我明白了ftok产生的问题,让我纠结了几天的问题。 ~~~结贴~~~

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值