【IPC通訊】key_t鍵和ftok函數

System V IPC分爲三種:node

  • 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
轉載請註明出處。
相關文章
相關標籤/搜索