ftok()函数的使用

在上一篇文章中,Mayuyu讲述了共享内存的原理以及使用方法。在创建共享内存之前,必须指定一个ID值,而这个ID值通常是通过现在要讲的ftok()函数得到。ftok()函数原型如下

其中参数fname是指定的文件名,这个文件必须是存在的而且可以访问的。id是子序号,它是一个8bit的整数。即范围是0~255

当函数执行成功,则会返回key_t键值,否则返回-1。在一般的UNIX中,通常是将文件的索引节点取出,然后在前面加上子序号就得到key_t的值。查看文件索引节点号的方法是使用命令:ls -i。例如,指定文件为share,索引号为787706,对应16进制为0xc04fa,如图

子序号设置为0,那么得到key值为0x000204fa,如下图

在上篇文章中,shmget()函数的参数key就是通过这种方式生成的。另外说明一下,在shmget()函数中的key,还可以用IPC_PRIVATE0,这样会建立新共享内存对象。

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

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

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

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

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

时间: 2024-10-27 14:14:25

ftok()函数的使用的相关文章

ftok函数的使用

ftok函数的定义:系统建立IPC通讯 (消息队列.信号量和共享内存) 时必须指定一个ID值.通常情况下,该id值通过ftok函数得到. 头文件 #include <sys/types.h> #include <sys/ipc.h> 函数原型: key_t ftok( const char * fname, int id ) fname就是你指定的文件名(已经存在的文件名),一般使用当前目录,如: key_t key; key = ftok(".", 1); 这

linux ftok()函数

函数原型 key_t ftok(const char *pathname, int proj_id); #pathname: 指定的文件名,该文件必须是存在而且可以访问 #proj_id:子序号,只有8个比特被使用(0-255) #当成功执行时,返回一个key_t值,失败返回-1 ftok实现原理 ftok返回的key_t在Linux中是一个32位的值,它通过取proj_id参数的最低8个有效位.包含pathname指定文件所属的文件系统的设备的次要设备号的最低8个有效位以及pathname所指

ftok函数例子

#include <stdio.h>#include <sys/types.h>#include <sys/ipc.h>int main( void ){ int id=2; //char a[]="hello world"; //int k=ftok(a,id);//该文件必须是存在而且可以访问的,否则返回-1,函数执行失败 int k=ftok("myfile",id);//格式为:"文件名",文件名的路径

linux ftok()函数 --多进程IPC之共享内存

系统建立IPC通讯(如消息队列.共享内存时)必须指定一个ID值.通常情况下,该id值通过ftok函数得到.ftok原型如下:key_t ftok( char * fname, int id ) fname就时你指定的文件名(该文件必须是存在而且可以访问的),id是子序号,虽然为int,但是只有8个比特被使用(0-255). 当成功执行的时候,一个key_t值将会被返回,否则 -1 被返回. 在一般的UNIX实现中,是将文件的索引节点号取出,前面加上子序号得到key_t的返回值.如指定文件的索引节

Linux中函数ftok如何产生键值

我们在做linux 进程间通信开发时,经常会用到ftok函数去产文唯一键值,那么这个键值是如何产生的呢. 函数原型:key_t ftok( const char * fname, int id );应用:key_t key=ftok(".",'A'); fname为已经存在的文件名,本文为"."表示当前目录: id为子序号,值范围只有8bits(0-255). 下面我们举例说明如何产生键值,代码ftok_test.c如下: #include <stdio.h&

PHP共享内存段实现,使用shmop函数实现内存共享

所谓内存共享:就是多个应用程序公用一个内存段,在A程序中可以获取B程序存储在这个内存段的数据,也就是数据共享. shmop是PHP提供的函数集,在配置PHP的时候使用 -enable-shmop后,就可以使用这个函数集提供的函数, shmop对LINUX更加友好,而对于WINDOWS来说就不怎样了,不支持CGI和CLI模式~有点尴尬. 来说说他提供的一些函数: ftok函数:生成一个数字或叫做键或key.$key = ftok(fileName, mode); 一般情况下,这个fileName可

IPC----消息队列二.函数接口

消息队列可以认为是一个消息链表,System V 消息队列使用消息队列标识符标识.具有足够特权的任何进程都可以往一个队列放置一个消息,具有足够特权的任何进程都可以从一个给定队列读出一个消息.在某个进程往一个队列写入消息之前,并不需要另外某个进程在该队列上等待消息的到达.System V 消息队列是随内核持续的,只有在内核重起或者显示删除一个消息队列时,该消息队列才会真正被删除.可以将内核中的某个特定的消息队列画为一个消息链表,如下图所示: 对于系统中每个消息队列,内核维护一个msqid_ds的信

linux系统调用函数

Linux应用编程学习笔记                                 周学伟 一.系统调用文件编程   1.文件打开函数 /***************************************************************************** 函数名:open 函数原型:int open(const char * pathname, int flags) int open(const char * pathname,int  flags,

ftok key值冲突

前两天遇到的关于ftok()函数的问题,当时发了帖子求助,解决后整理于此! 帖子在这儿:ftok产生的key冲突了 最近遇到一个问题,在用户b下创建共享内存失败,跟踪代码发现shmget的errno为17(要创建的这个共享内存已经存在了),可是在该用户下通过ipcs查看确实没有共享内存啊,后来发现,用户a下已经创建的共享内存与用户b要创建的共享内存冲突了,准确的说是key值冲突了,key值是通过ftok函数生成的. 上网查询了一个,ftok是根据文件i节点和调用ftok时的id值产生的,而且还给