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