55-键值与 ftok

在上一篇博文中,创建和获取 ipc 内核对象的方式所使用的键值都是需要事先约定好的。通常在编写程序的时候,这个键值可以放在公共头文件中,这样不同进程间如果需要获取相同的 ipc 内核对象,就使用公共头文件中约定好的 key 值。当然你也可以通过命令行传参数的方式来指定 key 值。

本文介绍一个函数 ftok,它可以根据路径和一个整数生成 key 值。如此你就可以约定好一个路径以及一个整数来取得相同的 key 了。

1. ftok 函数

#include <sys/types.h>
#include <sys/ipc.h>

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

参数 pathname 可以是目录路径,也可以是文件路径(随便什么类型的文件都可以)。

参数 proj_id 可以取任意整数,通常用项目的编号。实际上,ftok 在生成 key 的时候,只用了 proj_id 的低 8 位。

2. 实例

下面这个程序使用 ftok 生成 key 并将其打印到屏幕。

  • 代码
// ftok.c
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <stdlib.h>


int main(int argc, char* argv[]) {
  if (argc < 3) {
    printf("usage: %s <path> <id>\n", argv[0]);
    return -1; 
  }

  int id = atoi(argv[2]);

  key_t key = ftok(argv[1], id);

  if (key == -1) {
    perror("ftok");
    return -1; 
  }

  printf("key = 0x%08x\n", key);
  return 0;
}
  • 编译和运行
$ gcc ftok.c -o ftok
$ touch tmp // 生成一个文件
$ ./ftok tmp 10


这里写图片描述
图1 使用 ftok 生成 key

3. ftok 的算法

ftok 算法非常简单,它通过 stat 函数读取 pathname 的设备号和 inode 号,取设备号的低8位,inode 号的 低 16 位,以及 proj_id 的低 8 位组合成 key. key 具有下面的结构:

<proj_id 8 bit>-<dev 8 bit>-<inode 16 bit>

在图1 中,tmp 文件的信息如下:


这里写图片描述
图2 tmp 文件的信息

可以看到 tmp 的设备号为 2049(十六进制为 0x801),inode 号为 1002871(十六进制为 0xf4d77),再根据 proj_id,图1 中使用的是 10,(十进制 0xa),分别取:

proj_id 的低 8 位—— 0x0a
设备号低 8 位 —— 0x01
inode 号低 16 位—— 0x4d77

最后组合成成 key——0x0a014d77。

4. 总结

需要注意的是,ftok 并不保证 key 一定是唯一的,通常来说,只要不同的 ftok 使用不同的 pathname 和 proj_id,返回的 key 值都不相同(除非你的运气极佳:)。另外 man 手册中说明 proj_id 必须为非 0 值,否则其行为是未定义的。

  • ipc 内核对象的 key 值约定
  • 知道 ftok 函数的使用方法
  • 了解 ftok 函数的算法

练习:尝试编写一个 ftok 函数,功能和系统提供的一样。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值