ftok函数

ftok函数

  系统建立IPC通讯(消息队列、信号量和共享内存)时必须指定一个ID值。通常情况下,该id值通过ftok函数得到。

ftok原型

  头文件:

  #include <sys/types.h>

  #include <sys/ipc.h>

  如下:

  key_t ftok( char * fname, int id )

  fname就是你指定的文件名(已经存在的文件名),一般使用当前目录,如:

  key = ftok(".", 1); 这样就是将fname设为当前目录。

  id是子序号。

  在一般的UNIX实现中,是将文件的索引节点号取出,前面加上子序号得到key_t的返回值。

  如指定文件的索引节点号为65538,换算成16进制为0x010002,而你指定的ID值为38,换算成16进制为0x26,则最后的key_t返回值为0x26010002。

  查询文件索引节点号的方法是: ls -i

  当删除重建文件后,索引节点号由操作系统根据当时文件系统的使用情况分配,因此与原来不同,所以得到的索引节点号也不同。

  如果要确保key_t值不变,要么确保ftok的文件不被删除,要么不用ftok,指定一个固定的key_t值,比如:

  #define IPCKEY 0x111

  char path[256];

  sprintf( path, "%s/etc/config.ini", (char*)getenv("HOME") );

  msgid=ftok( path, IPCKEY );

  同一段程序,用于保证两个不同用户下的两组相同程序获得互不干扰的IPC键值。

  由于etc/config.ini(假定)为应用系统的关键配置文件,因此不存在被轻易删除的问题——即使被删,也会很快被发现并重建(此时应用系统也将被重起)。

一个ftok用于共享内存的实例:

 

 1 #include <sys/shm.h>
 2 #include <stdio.h>
 3 #include <errno.h>
 4 #include <string.h>
 5 #include <stdlib.h>
 6 #include <unistd.h>
 7 #include <sys/types.h>
 8 #include <sys/wait.h>
 9 
10 #define SIZE 1024
11 
12 extern int errno;
13 
14 int main()
15 {
16     int shmid;
17     char *shmptr;
18     key_t key;
19     pid_t pid;
20 
21     if((pid = fork()) < 0)
22     {
23         printf("fork error:%s\n", strerror(errno));
24         return -1;
25     }
26     else if(pid == 0)
27     {
28         sleep(2);
29         if((key = ftok("/dev/null", 1)) < 0)
30         {
31             printf("ftok error:%s\n", strerror(errno));
32             return -1;
33         }
34         if((shmid = shmget(key, SIZE, 0600)) < 0)
35         {
36             printf("shmget error:%s\n", strerror(errno));
37             exit(-1);
38         }
39 
40         if((shmptr = (char*)shmat(shmid, 0, 0)) == (void*)-1)
41         {
42             printf("shmat error:%s\n", strerror(errno));
43             exit(-1);
44         }
45         //memcpy(shmptr, "hello world", sizeof("hello world")); 
46         printf("child:pid is %d,share memory from %lx to %lx, content:%s\n",getpid(), (unsigned long)shmptr, (unsigned long)(shmptr + SIZE
47                     ), shmptr);
48         printf("child process sleep 2 seconds\n");
49         sleep(2);
50         if((shmctl(shmid, IPC_RMID, 0) < 0))
51         {
52             printf("shmctl error:%s\n", strerror(errno));
53             exit(-1);
54         }
55         exit(0);
56     }
57     //parent
58     else
59     {
60         if((key = ftok("/dev/null", 1)) < 0)
61         {
62             printf("ftok error:%s\n", strerror(errno));
63             return -1;
64         }
65         if((shmid = shmget(key, SIZE, 0600|IPC_CREAT|IPC_EXCL)) < 0)
66 
67         {
68             printf("shmget error:%s\n", strerror(errno));
69             exit(-1);
70         }
71 
72         if((shmptr = (char*)shmat(shmid, 0, 0)) == (void*)-1)
73         {
74             printf("shmat error:%s\n", strerror(errno));
75             exit(-1);
76         }
77         memcpy(shmptr, "hello world", sizeof("hello world"));
78         printf("parent:pid is %d,share memory from %lx to %lx, content:%s\n",getpid(),(unsigned long)shmptr, (unsigned long)(shmptr + SIZE
79                     ), shmptr);
80         printf("parent process sleep 2 seconds\n");
81         sleep(2);
82         if((shmctl(shmid, IPC_RMID, 0) < 0))
83         {
84             printf("shmctl error:%s\n", strerror(errno));
85             exit(-1);
86         }
87     }
88 
89     waitpid(pid,NULL,0);
90     exit(0);
91 }

 

转自:http://blog.csdn.net/aiwoziji13/article/details/6591937  

 

posted @ 2013-06-20 10:35  lpshou  阅读(2363)  评论(0编辑  收藏  举报