消息队列、信号量、共享内存经常用在Linux服务端编程的进程间通信环境中,两个进程需要通过这三种方式去通信,那就需要约定好一个唯一的id号来进行通信,正好文件的设备编号和节点是唯一的,可对其稍加改造以产生一个唯一的编号,这时ftok()函数刚好具备这个条件可以去干这么一件事情
函数原型 | 意义 |
---|---|
key_t ftok(const char *pathname, int id); | 成功返回key_t键值,出错:-1,错误原因存于error中 |
参数 | 意义 |
---|---|
pathname | 文件名必须是存在的而且可以访问的,与权限无关 |
id | 称为id子序号,只取低8位,1-255 |
到这里ftok基本就介绍完了,这里写个demo
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char **argv)
{
struct stat stat1;
if ( argc != 2 )
{
printf("usage: ftok < pathname >" );
exit(1);
}
stat( argv[1], &stat1 ) ;
printf("st_dev:%lx, st_ino:%lx, key:%x\n",
(unsigned long)stat1.st_dev, (unsigned long)stat1.st_ino, ftok(argv[1],0x01 ));
printf("st_dev:%lx, st_ino:%lx, key:%x\n",
(unsigned long)stat1.st_dev, (unsigned long)stat1.st_ino, ftok(argv[1],0x002 ));
exit(0);
}
以上demo的执行结果如下:
root@mcchen:/home/ftok# ls -i ftok
1846264 ftok
root@mcchen:/home/ftok# ./ftok ftok
st_dev:fc01, st_ino:1c2bf8, key:1012bf8
st_dev:fc01, st_ino:1c2bf8, key:2012bf8
通过执行结果可看出,ftok获取的键值是由ftok()函数的第二个参数的后8个bit,st_dev的后两位,st_ino的后四位构成的
这里就有一个疑问,如果把pathname删除掉然后再重新创建会怎样,返回的key和删除前的都一样吗?答案是否定的,也就是不一定
第一种情况:在arm 32位机器上执行结果截的图,inode改变了
第二种情况:在ubuntu64位机器上执行结果,inode没变
root@mcchen:/home/ftok# ls -i msg1.q
1846265 msg1.q
root@mcchen:/home/ftok# rm msg1.q
root@mcchen:/home/ftok# touch msg1.q
root@mcchen:/home/ftok# ls -i msg1.q
1846265 msg1.q
所以要确保key值不变,要么确保ftok()的文件不被删除,要么不用ftok(),指定一个固定的key值,至于以上的两种情况为什么查出来的inode一种会变化,一种不会变化,目前还不太清楚,如果读到这里的朋友们有知道的,欢迎评论区留言,多谢!