转载:

http://www.cnblogs.com/hjslovewcl/archive/2011/03/03/2314344.html

http://www.cnblogs.com/lihaozy/archive/2012/08/07/2626391.html

函数ftok把一个已存在的路径名和一个整数标识得转换成一个key_t值,称为IPC键:

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

DESCRIPTION 
       The ftok function uses the identity of the  file  named  by  the  given pathname  (which  must  refer  to an existing, accessible file) and the least significant 8 bits of proj_id (which must be nonzero) to generate  a  key_t  type  System  V  IPC  key。

该函数把从pathname导出的信息与id的低序8位组合成一个整数IPC键。

使用时候需要注意两点:

一/产生不同的键值需要不同的pathname和不同的proj_id做参数,不同pathname和通过一个proj_id可能会产生同一个键值.

示例代码1:

  #include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ipc.h>
/*
26 * === FUNCTION ======================================================================
27 * Name: main
28 * Description:
29 * =====================================================================================
30 */
int
main ( int argc, char *argv[] )
{
struct stat stat1; if ( argc != ) {
printf("need two arguments.\n");
return EXIT_FAILURE;
} stat(argv[], &stat1);
printf("st_dev:%lx, st_innode:%lx, key:%x\n",
(u_long)stat1.st_dev, (u_long)stat1.st_ino, ftok(argv[],0x0957)); return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */

运行结果1:

root@3me:/home/zfk/work/apue/chapter15# ./ .c
st_dev:, st_innode:18e02b2, key:570102b2
root@3me:/home/zfk/work/apue/chapter15#

结果分析:

ftok的典型实现调用stat函数,然后组合以下三个值: 
1.pathname所在的文件系统的信息(stat结构的st_dev成员) 
2.该文件在本文件系统内的索引节点号(stat结构的st_ino成员) 
3. proj_id的低序8位(不能为0)
从程序运行的结果可以看出,ftok调用返回的整数IPC键由proj_id的低序8位,st_dev成员的低序8位,st_info的低序16位组合而成。
 
因此:不能保证两个不同的路径名与同一个proj_id的组合产生不同的键,从实现原理上来看,不同pathname和同一个的proj_id的组合有产生相同键值的可能.
 
二/如果pathname指向的文件在程序运行期间有被删除和重新创建的操作,需要了解通过ftok前后两次操作得到的键值会发生变化.
 
分析:
a/根据上面所说键值产生原理,如果程序运行期间,有pathname文件的重新创建,则pathname指向文件的stat结构的st_ino必然会发生变化,因此会产生不同的键值.
b/因为ftok的实现存在这样的风险,即在访问同一共享内存的多个进程先后调用ftok函数的时间段中,如果 pathname指定的文件(或目录)被删除且重新创建,则文件系统会赋予这个同名文件(或目录)新的i节点信息,于是这些进程所调用的ftok虽然都能 正常返回,但得到的键值却并不能保证相同。由此可能造成的后果是,原本这些进程意图访问一个相同的共享内存对象,然而由于它们各自得到的键值不同,实际上 进程指向的共享内存不再一致;如果这些共享内存都得到创建,则在整个应用运行的过程中表面上不会报出任何错误,然而通过一个共享内存对象进行数据传输的目 的将无法实现。
 
依然运行以上的示例程序:
 
运行结果2:
 
首先用stat命令查看文件的innode节点,然后删除并重新创建文件,查看新创建文件的innnode节点。
 
root@3me:/home/zfk/work/apue/chapter15# stat
文件:""
大小: 块: IO 块: 普通文件
设备:801h/2049d Inode: 硬链接:
权限:(/-rw-r--r--) Uid:( / root) Gid:( / root)
最近访问:-- ::25.268217896 +
最近更改:-- ::25.268217896 +
最近改动:-- ::25.296217898 +
创建时间:-
root@3me:/home/zfk/work/apue/chapter15# ./
st_dev:, st_innode:18e02b3, key:570102b3
root@3me:/home/zfk/work/apue/chapter15# rm -rf
root@3me:/home/zfk/work/apue/chapter15# touch
root@3me:/home/zfk/work/apue/chapter15# stat
文件:""
大小: 块: IO 块: 普通空文件
设备:801h/2049d Inode: 硬链接:
权限:(/-rw-r--r--) Uid:( / root) Gid:( / root)
最近访问:-- ::50.276218127 +
最近更改:-- ::50.276218127 +
最近改动:-- ::50.276218127 +
创建时间:-
root@3me:/home/zfk/work/apue/chapter15# ./
st_dev:, st_innode:18e02aa, key:570102aa
root@3me:/home/zfk/work/apue/chapter15#

运行结果可以看出,虽然文件名称都是 1,并未改变,但由于中间发生了文件删除并重新创建的操作,前后两次所得到的键值已经不再相同。

避免此类问题最根本的方法,就是采取措施保证pathname所指定的文件(或目录)在共享内存的使用期间不被删除,不要使用有可能被删除的文件;或者干脆直接指定键值,而不借助ftok来获取键值。

ftok用法的更多相关文章

  1. Linux IPC实践(6) --System V消息队列(3)

    消息队列综合案例 消息队列实现回射客户/服务器   server进程接收时, 指定msgtyp为0, 从队首不断接收消息 server进程发送时, 将mtype指定为接收到的client进程的pid ...

  2. saltstack:使用教程之二高级模块用法Grains、Pillar

    1.grains用法: 在客户端服务启动的时候收集客户的基础信息,在配置发生变化后也可以通过master重新同步 显示一个客户端的所有项目: [root@node5 ~]# salt "no ...

  3. Flash访问模块FDS用法及常见问题—nRF5 SDK模块系列一

    FDS,全称Flash Data Storage,用来访问芯片内部Flash的.当你需要把数据存储在Flash中,或者读取Flash中的用户数据,或者更新或者删除Flash中的数据,那么FDS模块是你 ...

  4. EditText 基本用法

    title: EditText 基本用法 tags: EditText,编辑框,输入框 --- EditText介绍: EditText 在开发中也是经常用到的控件,也是一个比较必要的组件,可以说它是 ...

  5. jquery插件的用法之cookie 插件

    一.使用cookie 插件 插件官方网站下载地址:http://plugins.jquery.com/cookie/ cookie 插件的用法比较简单,直接粘贴下面代码示例: //生成一个cookie ...

  6. Java中的Socket的用法

                                   Java中的Socket的用法 Java中的Socket分为普通的Socket和NioSocket. 普通Socket的用法 Java中的 ...

  7. [转载]C#中MessageBox.Show用法以及VB.NET中MsgBox用法

    一.C#中MessageBox.Show用法 MessageBox.Show (String) 显示具有指定文本的消息框. 由 .NET Compact Framework 支持. MessageBo ...

  8. python enumerate 用法

    A new built-in function, enumerate() , will make certain loops a bit clearer. enumerate(thing) , whe ...

  9. [转载]Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法总结

    本文对Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法进行了详细的总结,需要的朋友可以参考下,希望对大家有所帮助. 详细解读Jquery各Ajax函数: ...

随机推荐

  1. 关于java实现断点续传的上传下载功能问题

    在web项目中上传文件夹现在已经成为了一个主流的需求.在OA,或者企业ERP系统中都有类似的需求.上传文件夹并且保留层级结构能够对用户行成很好的引导,用户使用起来也更方便.能够提供更高级的应用支撑. ...

  2. UVa 1600 Patrol Robot (BFS最短路 && 略不一样的vis标记)

    题意 : 机器人要从一个m * n 网格的左上角(1,1) 走到右下角(m, n).网格中的一些格子是空地(用0表示),其他格子是障碍(用1表示).机器人每次可以往4个方向走一格,但不能连续地穿越k( ...

  3. 微信小程序访问后台出现 对应的服务器证书无效。控制台输入 showRequestInfo() 可以获取更详细信息。

    检查微信开发者平台配置 https 服务端 nginx 配置 ssl 协议是否有效 在开发者工具中可以使用(详情 > 不校验合法域名.web-view(业务域名).TLS 版本以及 HTTPS ...

  4. Linux安装配置redis 、启动redis、redis设置密码

    由于间隔时间较长.机器的环境不同等等原因,所以每次安装redis的时候总是不那么顺利,所以这次我要做个笔记 文章大部分内容源于https://blog.csdn.net/gisredevelopmen ...

  5. maven 私服的setting.xml配置

    <?xml version="1.0" encoding="UTF-8"?> 2 <settings xmlns="http://m ...

  6. [LeetCode]-DataBase-Trips and Users

    The Trips table holds all taxi trips. Each trip has a unique Id, while Client_Id and Driver_Id are b ...

  7. Mybaits 运行原理流程时序图

    1 .初始化sqlsessionFactory 2openSession 3.getMapper返回接口的代理对象 包含了SqlSession对象 4.查询流程

  8. association实现懒加载分段级联查询

    这里讲的是人员和部门进行级联分布查询 1.首先在mybatis-config.xml里进行配置 <settings> <!--显示的指定每个我们需要更改的配置的值,即使他是默认的.防 ...

  9. C# WPF 漂亮的loading 效果

    <UserControl x:Class="TestLoadPic.Loading" xmlns="http://schemas.microsoft.com/win ...

  10. EDM杂谈:第一个屏幕的定义和特点

    在EDM营销中,经常会碰到第一个屏幕这个概念.这是什么意思呢?博主跟大家介绍一下. 图一:博文配图 这个主要是指用户在打开邮件时不需要滚动屏幕就可以看到的邮件内容.因为用户第一眼就可以看到,因此这部分 ...