ftok()函数解析
ftok
消息队列、信号灯、共享内存常用在Linux服务端编程的进程间通信环境中。而此三类编程函数在实际项目中都是用System V IPC函数实现的。System V IPC函数名称和说明如下表15-1所示。
表15-1 System V IPC函数
消息队列 |
信号灯 |
共享内存区 |
|
头文件 |
<sys/msg.h> |
<sys/sem.h> |
<sys/shm.h> |
创建或打开IPC函数 |
msgget |
semget |
shmget |
控制IPC操作的函数 |
msgctl |
semctl |
shmctl |
IPC操作函数 |
msgsnd msgrcv |
semop |
shmat shmdt |
1.key_t键和ftok函数
函数ftok把一个已存在的路径名和一个整数标识符转换成一个key_t值,称为IPC键值(也称IPC key键值)。ftok函数原型及说明如下:
key_t ftok( char * fname, int id )
ftok(把一个已存在的路径名和一个整数标识符转换成IPC键值) |
所需头文件 |
#include <sys/types.h> #include <sys/ipc.h> |
函数说明 |
把从pathname导出的信息与id的低序8位组合成一个整数IPC键 |
函数原型 |
key_t ftok(const char *pathname, int proj_id) |
函数传入值 |
pathname:指定的文件,此文件必须存在且可存取 |
proj_id:计划代号(project ID) |
|
函数返回值 |
成功:返回key_t值(即IPC 键值) |
出错:-1,错误原因存于error中 |
|
附加说明 |
key_t一般为32位的int型的重定义 |
ftok的典型实现是调用stat函数,然后组合以下三个值:
- pathname所在的文件系统的信息(stat结构的st_dev成员)。
- 该文件在本文件系统内的索引节点号(stat结构的st_ino成员)。
- proj_id的低序8位(不能为0)。
上述三个值的组合产生一个32位键。
2. ftok函数代码举例
ftok.c源代码如下:
#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],0x579 )) ;printf("st_dev:%lx, st_ino:%lx, key:%x\n", (unsigned long)stat1.st_dev, (unsigned long)stat1.st_ino , ftok(argv[1],0x118 )) ;printf("st_dev:%lx, st_ino:%lx, key:%x\n", (unsigned long)stat1.st_dev, (unsigned long)stat1.st_ino , ftok(argv[1],0x22 )) ;printf("st_dev:%lx, st_ino:%lx, key:%x\n", (unsigned long)stat1.st_dev, (unsigned long)stat1.st_ino , ftok(argv[1],0x33 )) ;exit(0) ;
}
编译 gcc ftok.c –o ftok
运行 ./ftok /tmp,执行结果如下:
从上面程序可以看出,通过ftok返回的是根据文件(pathname)信息和计划编号(proj_id)合成的IPC key键值,从而避免用户使用key值的冲突。proj_id值的意义让一个文件也能生成多个IPC key键值。ftok利用同一文件最多可得到IPC key键值0xff(即256)个,因为ftok只取proj_id值二进制的后8位,即16进制的后两位与文件信息合成IPC key键值。
有关该函数的三个常见问题:
- pathname是目录还是文件的具体路径,是否可以随便设置;
- pathname指定的目录或文件的权限是否有要求;
- proj_id是否可以随便设定,有什么限制条件。
解答:
- ftok根据路径名,提取文件信息,再根据这些文件信息及project ID合成key,该路径可以随便设置。
- 该路径是必须存在的,ftok只是根据文件inode在系统内的唯一性来取一个数值,和文件的权限无关。
- proj_id是可以根据自己的约定,随意设置。这个数字,有的称之为project ID; 在UNIX系统上,它的取值是1到255;
关于ftok()函数的一个陷阱
- 在使用ftok()函数时,里面有两个参数,即fname和id,fname为指定的文件名,而id为子序列号,这个函数的返回值就是key,它与指定的文件的索引节点号和子序列号id有关,这样就会给我们一个误解,即只要文件的路径,名称和子序列号不变,那么得到的key值永远就不会变。
- 事实上,这种认识是错误的,想想一下,假如存在这样一种情况:在访问同一共享内存的多个进程先后调用ftok()时间段中,如果fname指向的文件或者目录被删除而且又重新创建,那么文件系统会赋予这个同名文件新的i节点信息,于是这些进程调用的ftok()都能正常返回,但键值key却不一定相同了。由此可能造成的后果是,原本这些进程意图访问一个相同的共享内存对象,然而由于它们各自得到的键值不同,实际上进程指向的共享内存不再一致;如果这些共享内存都得到创建,则在整个应用运行的过程中表面上不会报出任何错误,然而通过一个共享内存对象进行数据传输的目 的将无法实现。
- 所以要确保key值不变,要么确保ftok()的文件不被删除,要么不用ftok(),指定一个固定的key值。
ftok()函数解析相关推荐
- ftok()函数深度解析
关于ftok函数,先不去了解它的作用来先说说为什么要用它,共享内存,消息队列,信号量它们三个都是找一个中间介质,来进行通信的,这种介质多的是.就是怎么区分出来,就像唯一一个身份证来区分人一样.你随便来 ...
- ftok函数参数解析
转载https://blog.csdn.net/u013485792/article/details/50764224 关于ftok函数,先不去了解它的作用来先说说为什么要用它,共享内存,消息队列,信 ...
- linux中ftok的作用,Unix/Linux编程之ftok函数用法
linux 中ftok函数的用法 1.函数作用: 系统建立IPC通讯(如消息队列.共享内存时)必须指定一个ID值.通常情况下,该id值通过ftok函数得到 2.函数原型: #include #incl ...
- 正文6:System V共享内存(修正版)及ftok函数讲解
文章目录 0.linux共享内存相关操作命令 1)ipcs用法 2)ipcrm用法 1.共享内存的通信原理 0)特点 1)定义: 2)原理: 3)特别提醒: 4)原理图: 5)补充 2.为什么共享内存 ...
- linux环境编程-- ftok()函数
系统建立IPC通讯(如消息队列.共享内存时)必须指定一个ID值.通常情况下,该id值通过ftok函数得到. ftok原型如下: key_t ftok( char * fname, int id ) f ...
- oracle rpad mysql_Oracle生成不重复票号与LPAD,RPAD与NEXTVAL函数解析
SELECT TO_CHAR(SYSDATE,'YYMMDD')||LPAD(REFUNDSEQ.NEXTVAL,6,'0') AS RES_ORDER_NO FROM DUAL 该语句拼接 时间 与 ...
- json数据解析_VBA 实践指南 -- Split函数解析Json数据
什么是JSON? JSON(JavaScript Object Notation) 是一种及其轻量级的数据交换格式,它是 ECMAScript (欧洲计算机协会制定的JavaScript规范)的一个子 ...
- C/C++ sizeof函数解析——解决sizeof求结构体大小的问题
C/C++ sizeof函数解析--解决sizeof求结构体大小的问题 参考文章: (1)C/C++ sizeof函数解析--解决sizeof求结构体大小的问题 (2)https://www.cnbl ...
- ftok file php,Linux和PHP中的ftok函数返回值不一致问题跟踪
在IPC中中,我们经常事情ftok函数来获取key,来作为获取消息队列id.共享存储标识和信号量ID.在项目中使用了php进程和linux进程通信,采用了消息队列的方式,但是结果表现为php中的fto ...
最新文章
- 创建一个好的Sprint Backlog 的8个小贴士
- 动态规划走楼梯_负重爬楼梯、过草地,服贸会六足机械人展示“送水到家”
- .NET Core开发日志——从ASP.NET Core Module到KestrelServer
- 正则表达式30分钟入门教程(转)
- 案例:Redis 问题汇总和相关解决方案
- 有了这些接口测试用例+工具,测试效率想不提升都难
- Window平台下通过cmd命令查看端口占用、查看进程、结束进程
- 计算机网络基础试题2,计算机网络基础试题库2
- 疯狂java讲义第七章课后习题答案
- 机器学习常见概率模型
- 应用交付能给客户带来什么价值?
- linux socket错误提示errno分析
- 聊聊MultipartFile的transferTo方法
- 安装pyinstaller报错----Fatal error in launcher:
- js 全屏与退出全屏
- 【Tomcat】tomcat9使用tomcat7-maven-plugin插件配置及其他一系列配置问题解决
- matlab画一维波动方程,一维波动方程的数值解
- 2023年留学基金委(CSC)公派访问学者博士后项目选派办法及解读
- 短线操作技巧,如何判断次日收阳
- FastStone Capture 8.9 注册机/注册码
热门文章
- VBA代码自学收集(150例)
- 【ceph】Rados的客户端RadosClient|MonClient|Osdc
- 大数据增量采集OGGAdapter的安装部署与相关配置
- Unity Sockect实现画面实时传输
- 使用Xamarin进行移动开发
- windows多个不同java共存
- mysql时区错误The server time zone value ‘�й���ʱ��‘
- 零信任网络的一个重要功能:信任管理
- 区块链技术革命:关键时刻的新洞察和实践|筱静观察2019第10期
- 前端中国标准时间转化为yyyy-MM-dd HH:mm:ss