key_t IPC键和ftok函数详解和剖析
統建立IPC通訊(如消息隊列、共享內存時)必須指定一個ID值。通常情況下,該id值通過ftok函數得到。
ftok原型如下:
key_t ftok( char * fname, int id )
fname就時你指定的文件名(該文件必須是存在而且可以訪問的),id是子序號,雖然為int,但是只有8個比特被使用(0-255)。
當成功執行的時候,一個key_t值將會被返回,否則 -1 被返回。
在一般的UNIX實現中,是將文件的索引節點號取出,前面加上子序號得到key_t的返回值。如指定文件的索引節點號為65538,換算成16進制為 0x010002,而你指定的ID值為38,換算成16進制為0x26,則最后的key_t返回值為0x26010002。
查詢文件索引節點號的方法是: ls -i
?
例如:
??#include??????? "unpipc.h"
? int main(int argc, char **argv)
? {
??????? struct stat???? stat;
??????? if (argc != 2)
??????????????? err_quit("usage: ftok ");
??????? Stat(argv[1], &stat);
??????? printf("st_dev: %lx, st_ino: %lx, key: %x/n",
????????????? (u_long) stat.st_dev,(u_long) stat.st_ino,
????????????? Ftok(argv[1], 0x57));
??????? exit(0);
? }
程序運行結果:
???? ?[cbs@linux svipc]$ ./ftok? /tmp/mysql.sock
???? st_dev: 802, st_ino: 34219, key: 57024219
1.pathname所在的文件系統的信息(stat結構的st_dev成員)
2.該文件在本文件系統內的索引節點號(stat結構的st_ino成員)
3. proj_id的低序8位(不能為0) 從程序運行的結果可以看出,ftok調用返回的整數IPC鍵由proj_id的低序8位(57),st_dev成員的低序8位(02),st_info的低序16位組合而成(4219)。 ? 注:兩進程如在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鍵。
{
??? 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;
}
總結
以上是生活随笔為你收集整理的key_t IPC键和ftok函数详解和剖析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++(STL):34--- multi
- 下一篇: (十三) 深入浅出TCPIP之TCP套接