【IPC通信】key_t键和ftok函数

System V IPC分为三种:

  • System V消息队列
  • System V信号量
  • System V共享内存区

这三种类型的IPC使用key_t值做为它们的名字。key_t这个数据类型在<sys/types.h>有定义,通常是一个至少32位的整数。

我们通常使用ftok()函数(可以如此记忆:file to key)把一个已存在的路径名和一个整数标识符转换成一个key_t值,称为IPC键。(当然,我们也可以不用ftok函数来生成该键,指定一个整数也是可以的,当然你需要考虑键的正负问题)。

看下ftok的声明:

#include <sys/ipc.h>
/* Generates key for System V style IPC.  */
key_t ftok (const char *pathname, int proj_id);

pathname 通常是跟本应用用关的目录;proj_id指的是本应用所用到的IPC的一个序列号;成功返回IPC键,失败返回-1;

注:两进程如在pathname和proj_id上达成一致(或约定好),双方就都能够通过调用ftok函数得到同一个IPC键。

那么ftok是怎么实现的呢?《UNIX网络编程》上讲到,ftok的实现是组合了三个值:

  • pathname所在文件系统的信息(stat结构的st_dev成员)
  • pathname在本文件系统内的索引节点号(stat结构的st_ino成员)
  • id的低序8位(不能为0)

具体如何组合的,根据系统实现而不同。

使用ftok()需要注意的问题:

 

  • pathname指定的目录(文件)必须真实存在且调用进程可访问,否则ftok返回-1;
  • pathname指定的目录(文件)不能在程序运行期间删除或创建。因为文件每次创建时由系统赋予的索引节点可能不一样。这样一来,通过同一个pathname与proj_id就不能保证生成同一个IPC键。

附:文件属性结构

struct stat
{
    dev_t         st_dev;      /* device */
    ino_t         st_ino;      /* inode */
    mode_t        st_mode;     /* protection */
    nlink_t       st_nlink;    /* number of hard links */
    uid_t         st_uid;      /* user ID of owner */
    gid_t         st_gid;      /* group ID of owner */
    dev_t         st_rdev;     /* device type (if inode device) */
    off_t         st_size;     /* total size, in bytes */
    blksize_t     st_blksize;  /* blocksize for filesystem I/O */
    blkcnt_t      st_blocks;   /* number of blocks allocated */
    time_t        st_atime;    /* time of last access */
    time_t        st_mtime;    /* time of last modification */
    time_t        st_ctime;    /* time of last status change */
};

获取文件属性的函数有如下几个:

int stat(const char *file_name, struct stat *buf);
int fstat(int filedes, struct stat *buf);
int lstat(const char *file_name, struct stat *buf);

 

下面通过例子来看一下如何获取:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int main()
{
    const char fname[] = "main.c";
    struct stat stat_info;

    if(0 != stat(fname, &stat_info))
    {
        perror("取得文件信息失败!");
        exit(1);
    }

    printf("文件所在设备编号:%ld\r\n", stat_info.st_dev);
    printf("文件所在文件系统索引:%ld\r\n", stat_info.st_ino);
    printf("文件的类型和存取的权限:%d\r\n", stat_info.st_mode);
    printf("连到该文件的硬连接数目:%d\r\n", stat_info.st_nlink);
    printf("文件所有者的用户识别码:%d\r\n", stat_info.st_uid);
    printf("文件所有者的组识别码:%d\r\n", stat_info.st_gid);
    printf("装置设备文件:%ld\r\n", stat_info.st_rdev);
    printf("文件大小:%ld\r\n", stat_info.st_size);
    printf("文件系统的I/O缓冲区大小:%ld\r\n", stat_info.st_blksize);
    printf("占用文件区块的个数(每一区块大小为512个字节):%ld\r\n", stat_info.st_blocks);
    printf("文件最近一次被存取或被执行的时间:%ld\r\n", stat_info.st_atime);
    printf("文件最后一次被修改的时间:%ld\r\n", stat_info.st_mtime);
    printf("最近一次被更改的时间:%ld\r\n", stat_info.st_ctime);
    return 0;
}

编译并执行输出:

$ gcc -o getstat main.c

$ ./getstat

文件所在设备编号:2051

文件所在文件系统索引:61079722

文件的类型和存取的权限:33188

连到该文件的硬连接数目:1

文件所有者的用户识别码:502

文件所有者的组识别码:503

装置设备文件:0

文件大小:1210

文件系统的I/O缓冲区大小:4096

占用文件区块的个数(每一区块大小为512个字节):8

文件最近一次被存取或被执行的时间:1320997735

文件最后一次被修改的时间:1320994242

最近一次被更改的时间:1320994242

 

2011-11-11  任洪彩  qdurenhongcai@163.com

转载请注明出处。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]中提到,ftok函数的功能是通过文件信息和计划编号合成一个IPC key值。该函数的返回值是一个key_t类型的值,即IPC值。参数pathname是指定的文件路径,该文件必须存在且可存取。参数proj_id是计划代号,用于让一个文件能够生成多个IPC key值。ftok函数利用同一文件最多可得到256个IPC key值,因为它只取proj_id值二进制的后8位,即16进制的后两位与文件信息合成IPC key值。 引用\[2\]中给出了ftok函数的声明,它包含在sys/ipc.h头文件中。 引用\[3\]中解释了通常使用ftok函数将一个已存在的路径名和一个整数标识符转换成一个IPC。这个可以通过ftok函数生成,也可以直接指定一个整数。需要注意的是,的正负问题也需要考虑。 综上所述,key_t ftok函数的作用是通过文件信息和计划编号生成一个IPC值。 #### 引用[.reference_title] - *1* [key_tftok函数](https://blog.csdn.net/weixin_36750623/article/details/83044571)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [【IPC通信key_tftok函数](https://blog.csdn.net/oNelson123/article/details/109660680)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值