关于ftok函数,先不去了解它的作用来先说说为什么要用它,共享内存,消息队列,信号量它们三个都是找一个中间介质,来进行通信的,这种介质多的是。就是怎么区分出来,就像唯一一个身份证来区分人一样。你随便来一个就行,就是因为这。只要唯一就行,就想起来了文件的设备编号和节点,它是唯一的,但是直接用它来作识别好像不太好,不过可以用它来产生一个号。ftok()就出场了。ftok函数具体形式如下:

key_t ftok(const char *pathname, int proj_id);

其中参数fname是指定的文件名,这个文件必须是存在的而且可以访问的。id是子序号,它是一个8bit的整数。即范围是0~255。当函数执行成功,则会返回key_t键值,否则返回-1。在一般的UNIX中,通常是将文件的索引节点取出,然后在前面加上子序号就得到key_t的值。


有关该函数的三个常见问题:

1.pathname是目录还是文件的具体路径,是否可以随便设置

2.pathname指定的目录或文件的权限是否有要求

3.proj_id是否可以随便设定,有什么限制条件

解答:

   1、ftok根据路径名,提取文件信息,再根据这些文件信息及project ID合成key,该路径可以随便设置。

2、该路径是必须存在的,ftok只是根据文件inode在系统内的唯一性来取一个数值,和文件的权限无关。

3、proj_id是可以根据自己的约定,随意设置。这个数字,有的称之为project ID; 在UNIX系统上,它的取值是1到255;

简单验证:

用到的代码,文件wxyuan.c:

    #include <stdio.h>  #include <sys/sem.h>  #include <stdlib.h>  int main()  {  key_t semkey;  if((semkey = ftok("./test", 1))<0)  {  printf("ftok failed\n");  exit(EXIT_FAILURE);  }     printf("ftok ok ,semkey = %d\n", semkey);  return 0;  } 

关于ftok()函数的一个陷阱

在使用ftok()函数时,里面有两个参数,即fname和id,fname为指定的文件名,而id为子序列号,这个函数的返回值就是key,它与指定的文件的索引节点号和子序列号id有关,这样就会给我们一个误解,即只要文件的路径,名称和子序列号不变,那么得到的key值永远就不会变。

事实上,这种认识是错误的,想想一下,假如存在这样一种情况:在访问同一共享内存的多个进程先后调用ftok()时间段中,如果fname指向的文件或者目录被删除而且又重新创建,那么文件系统会赋予这个同名文件新的i节点信息,于是这些进程调用的ftok()都能正常返回,但键值key却不一定相同了。由此可能造成的后果是,原本这些进程意图访问一个相同的共享内存对象,然而由于它们各自得到的键值不同,实际上进程指向的共享内存不再一致;如果这些共享内存都得到创建,则在整个应用运行的过程中表面上不会报出任何错误,然而通过一个共享内存对象进行数据传输的目 的将无法实现。

这是一个很重要的问题,希望能谨记!!!

所以要确保key值不变,要么确保ftok()的文件不被删除,要么不用ftok(),指定一个固定的key值。

Ubuntu下,ftok()产生键值的原理:

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>int main()
{char    filename[50];struct stat     buf;int     ret;strcpy( filename, "/home/satellite/" );ret = stat( filename, &buf );if( ret ){printf( "stat error\n" );return -1;}printf( "the file info: ftok( filename, 0x27 ) = %x, st_ino = %x, st_dev= %x\n", ftok( filename, 0x27 ), buf.st_ino, buf.st_dev );return 0;
}

执行该源码:

satellite@ubuntu:~/test$ ./wxyuan
the file info: ftok( filename, 0x27 ) = 27012eef, st_ino = e2eef, st_dev= 801

通过执行结果可看出,ftok获取的键值是由ftok()函数的第二个参数的后8个bit,st_dev的后两位,st_ino的后四位构成的。


有关st_dev和st_ino的定义如下:
函数:int stat( const char *file_name, struct stat *buf )
函数说明:通过文件名filename,获取文件信息,并保存在buf所指的结构体stat中。
返回值:成功执行返回0,失败返回-1,错误代码存于errno
struct stat结构体的定义如下:
/usr/include/asm/stat.hstruct stat {unsigned long  st_dev;//文件的设备编号unsigned long  st_ino;//节点unsigned short st_mode; //文件的类型和存取的权限unsigned short st_nlink;//连到该文件的硬连接数目,刚建立的文件值为1unsigned short st_uid; //用户IDunsigned short st_gid; //组IDunsigned long st_rdev; unsigned long  st_size;unsigned long st_blksize;unsigned long  st_blocks;unsigned long  st_atime;unsigned long st_atime_nsec;unsigned long  st_mtime;unsigned long st_mtime_nsec;unsigned long  st_ctime;unsigned long st_ctime_nsec;unsigned long  __unused4;unsigned long  __unused5;
};

ftok()函数深度解析相关推荐

  1. 语言中拟合函数 计算aic_Go语言函数深度解析(中)

    上回函数深度解析给大家聊了一些函数的基本知识,不知道还有没有人记得,不记得赶紧回去复习! 他们是 go语言中函数的基本原理 单/多个同/不同类型参数 单/多个同/不同类型返回值 值传递,引用传递 函数 ...

  2. sprintf函数_三分钟学 Go 语言——函数深度解析(下) 可变参数

    接连两篇函数专题深度解析,相信大家已经对函数的语法有了深入的了解. 函数简单使用和基本知识解析 匿名函数和闭包 五一放假期间,我懂得,估计你们都不想学习. 小熊这两天因为个人种种令人难受的原因,没有能 ...

  3. ftok函数参数解析

    转载https://blog.csdn.net/u013485792/article/details/50764224 关于ftok函数,先不去了解它的作用来先说说为什么要用它,共享内存,消息队列,信 ...

  4. go float64 转int_深挖Go函数之深度解析(下):可变参数

    接连两篇函数专题深度解析,相信大家已经对函数的语法有了深入的了解. 函数简单使用和基本知识解析 匿名函数和闭包 这次给大家带来了一个函数的特性[可变参数],作为函数专题的结束. 有没有发现? 我们有时 ...

  5. 深度解析源码strcpy函数

    深度解析源码strcpy函数@TOC 前言 提示:这里可以添加本文要记录的大概内容: 本文将介绍c语言中string.h中strcpy函数的源码解析 提示:以下是本篇文章正文内容,下面案例可供参考 一 ...

  6. C++深度解析 类中的函数重载 -- 全局函数,普通成员函数,静态成员函数(28)

    C++深度解析 类中的函数重载 -- 全局函数,普通成员函数,静态成员函数(28) 函数重载的回顾 函数重载的本质为相互独立的不同函数 C++中通过函数名和函数参数确定函数调用 无法直接通过函数名得到 ...

  7. ftok()函数解析

    ftok 消息队列.信号灯.共享内存常用在Linux服务端编程的进程间通信环境中.而此三类编程函数在实际项目中都是用System V IPC函数实现的.System V IPC函数名称和说明如下表15 ...

  8. 单文件浏览器_图文并茂深度解析浏览器渲染原理,包看懂超值得收藏

    在我们面试过程中,面试官经常会问到这么一个问题,那就是从在浏览器地址栏中输入URL到页面显示,浏览器到底发生了什么?这个问题看起来是老生常谈,但是这个问题回答的好坏,确实可以很好的反映出面试者知识的广 ...

  9. 深度解析ASP.NET2.0中的Callback机制

    callback的一般使用方法还算简单,直接参照msdn的帮助和范例就足够了.但是想要真正用好.用精,或者想开发一些基于callback机制的WEB组件,那么,就要先深入了解callback的实现机制 ...

最新文章

  1. cad中拖动文字时卡顿_技巧CAD制图的一百多个技巧,都学会你就逆天了!(下)...
  2. Chrome安装metamask
  3. C++ 面向对象的三大特性和五个原则?
  4. 下载的c语言程序代码怎么运行,CFree怎么运行程序 编译运行C语言程序代码的方法...
  5. 在Oracle用SQL处理以 System.currentTimeMillis
  6. linux查看mariadb安装卸载,MySQL——在Linux下安装和卸载MariaDB
  7. 8月28日服务器例行维护公告,天涯明月刀8月28日更新了什么-8月28日更新内容介绍...
  8. 《Android游戏编程入门经典》——4.6节问与答
  9. MUSIC算法及MATLAB实现
  10. 数学魔鬼表达式——第三天
  11. matlab求解联名方程组带三角函数的,matlab三角函数方程组
  12. Windows开启卓越性能模式,一键睿频
  13. 阿兰图灵和冯诺依曼,谁才是可称得起计算机之父呢?
  14. “未安装任何音频输出设备”解决办法
  15. 个人网站Timonj(Personal website)
  16. 【基础】存储过程IN、OUT、INOUT参数模式
  17. python编程入门书-最适合Python初学者的6本书籍推荐「必须收藏」
  18. CAN总线控制器SJA1000
  19. 中国有句俗语叫“三天打鱼两天晒网”。某人从2010年1月1日起开始“三天打鱼两天晒网”,问这个人在以后的某一天中是“打鱼”还是“晒网”。
  20. 日内回转交易(股票)——Python量化

热门文章

  1. ecs硬盘数据迁移_如何将数据从旧硬盘完美迁移到新硬盘
  2. 冰封王座1.17版新英雄研究之火焰领主
  3. 山东省2023年春季高考技能测试电子技术类专业试题
  4. mybatis-plus使用distinct
  5. Flink KafkaSink
  6. 纯前端如何在网页端播放摄像头的实时画面
  7. html5 css3光晕
  8. 正则表达式练习(实验楼会员课程)
  9. JAVA两种实现文本敏感词检测的方式
  10. 童话大王郑渊洁的现代私塾