• ftok用法


    转载:

    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:

     18 #include <stdlib.h>
     19 #include <stdio.h>
     20 #include <unistd.h>
     21 #include <stdlib.h>
     22 #include <sys/stat.h>
     23 #include <sys/types.h>
     24 #include <sys/ipc.h>
     25 /* 
     26  * ===  FUNCTION  ======================================================================
     27  *         Name:  main
     28  *  Description:  
     29  * =====================================================================================
     30  */
     31     int
     32 main ( int argc, char *argv[] )
     33 {
     34     struct stat stat1;
     35 
     36     if ( argc != 2 ) {
     37         printf("need two arguments.
    ");
     38         return EXIT_FAILURE;
     39     }
     40 
     41     stat(argv[1], &stat1);
     42     printf("st_dev:%lx, st_innode:%lx, key:%x
    ",
     43             (u_long)stat1.st_dev, (u_long)stat1.st_ino, ftok(argv[1],0x0957));
     44 
     45     return EXIT_SUCCESS;
     46 }       /* ----------  end of function main  ---------- */

    运行结果1:

    root@3me:/home/zfk/work/apue/chapter15# ./2 2.c
    st_dev:801, 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 1
      文件:"1"
      大小:5             块:8          IO 块:4096   普通文件
    设备:801h/2049d    Inode:26084019    硬链接:1
    权限:(0644/-rw-r--r--)  Uid:(    0/    root)   Gid:(    0/    root)
    最近访问:2014-09-09 17:57:25.268217896 +0800
    最近更改:2014-09-09 17:57:25.268217896 +0800
    最近改动:2014-09-09 17:57:25.296217898 +0800
    创建时间:-
    root@3me:/home/zfk/work/apue/chapter15# ./2 1
    st_dev:801, st_innode:18e02b3, key:570102b3
    root@3me:/home/zfk/work/apue/chapter15# rm -rf 1
    root@3me:/home/zfk/work/apue/chapter15# touch 1
    root@3me:/home/zfk/work/apue/chapter15# stat 1
      文件:"1"
      大小:0             块:0          IO 块:4096   普通空文件
    设备:801h/2049d    Inode:26084010    硬链接:1
    权限:(0644/-rw-r--r--)  Uid:(    0/    root)   Gid:(    0/    root)
    最近访问:2014-09-09 17:57:50.276218127 +0800
    最近更改:2014-09-09 17:57:50.276218127 +0800
    最近改动:2014-09-09 17:57:50.276218127 +0800
    创建时间:-
    root@3me:/home/zfk/work/apue/chapter15# ./2 1
    st_dev:801, st_innode:18e02aa, key:570102aa
    root@3me:/home/zfk/work/apue/chapter15# 

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

    避免此类问题最根本的方法,就是采取措施保证pathname所指定的文件(或目录)在共享内存的使用期间不被删除,不要使用有可能被删除的文件;或者干脆直接指定键值,而不借助ftok来获取键值。
  • 相关阅读:
    QSet<T>自定义类型需要定义==和qHash()函数
    《左耳听风》-ARTS-打卡记录-第十三周
    Windows中对窗口进行剪切
    Markdown 编写规范
    【洛谷 P1033】自由落体
    【GOJ 3032】司愁之路
    动态规划基础 3-解题报告
    前缀、中缀、后缀互相转换
    【GOJ 3015】疯狂外星人
    【GOJ 3010】有趣的数
  • 原文地址:https://www.cnblogs.com/3me-linux/p/3963134.html
Copyright © 2020-2023  润新知