天天看點

55-鍵值與 ftok1. ftok 函數2. 執行個體3. ftok 的算法4. 總結

在上一篇博文中,建立和擷取 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 < ) {
    printf("usage: %s <path> <id>\n", argv[]);
    return -; 
  }

  int id = atoi(argv[]);

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

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

  printf("key = 0x%08x\n", key);
  return ;
}
           
  • 編譯和運作
$ gcc ftok.c -o ftok
           
$ touch tmp // 生成一個檔案
$ ./ftok tmp 
           
55-鍵值與 ftok1. ftok 函數2. 執行個體3. ftok 的算法4. 總結

圖1 使用 ftok 生成 key

3. ftok 的算法

ftok 算法非常簡單,它通過 stat 函數讀取 pathname 的裝置号和 inode 号,取裝置号的低8位,inode 号的 低 16 位,以及 proj_id 的低 8 位組合成 key. key 具有下面的結構:

在圖1 中,tmp 檔案的資訊如下:

55-鍵值與 ftok1. ftok 函數2. 執行個體3. ftok 的算法4. 總結

圖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 函數,功能和系統提供的一樣。

繼續閱讀