系统建立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
第一个是写数据:
-
/***** testwrite.c *******/
-
#include
-
#include
-
#include
-
#include
-
typedef struct{
-
char name[4];
-
int age;
-
} people;
-
main(int argc, char** argv)
-
{
-
int shm_id,i;
-
key_t key;
-
char temp;
-
people *p_map;
-
char* name = "/dev/shm/myshm2";
-
key = ftok(name,0);
-
if(key==-1)
-
perror("ftok error");
-
/*先用ftok创建一个key,再调用shmget,创建一块共享内存区域*/
-
shm_id=shmget(key,4096,IPC_CREAT);
-
if(shm_id==-1)
-
{
-
perror("shmget error");
-
return;
-
}
-
/*将这块共享内存区附加到自己的内存段*/
-
p_map=(people*)shmat(shm_id,NULL,0);
-
temp='a';
-
for(i = 0;i<10;i++)
-
{
-
temp+=1;
-
memcpy((*(p_map+i)).name,&temp,1);
-
(*(p_map+i)).age=20+i;
-
}
-
/*写数据完毕,将其从自己的内存段中“删除”出去*/
-
if(shmdt(p_map)==-1)
-
perror(" detach error ");
-
}
2、读数据
-
/*读进程首先要得到那块内存块,这个时候,ftok根据文件名和ID创建的key就
-
很用了,步骤同创建是一样的*/
-
/********** testread.c ************/
-
#include
-
#include
-
#include
-
#include
-
typedef struct{
-
char name[4];
-
int age;
-
} people;
-
main(int argc, char** argv)
-
{
-
int shm_id,i;
-
key_t key;
-
people *p_map;
-
char* name = "/dev/shm/myshm2";
-
key = ftok(name,0);
-
if(key == -1)
-
perror("ftok error");
-
shm_id = shmget(key,4096,IPC_CREAT);
-
if(shm_id == -1)
-
{
-
perror("shmget error");
-
return;
-
}
-
p_map = (people*)shmat(shm_id,NULL,0);
-
for(i = 0;i<10;i++)
-
{
-
printf( "name:%s\n",(*(p_map+i)).name );
-
printf( "age %d\n",(*(p_map+i)).age );
-
}
-
if(shmdt(p_map) == -1)
-
perror(" detach error ");
-
}
注:事实上,ftok函数仅仅是根据文件名和ID生成一个起标识作用的key,根据《GNU Linux编程指南》说,Linux下实现这一函数还有点问题,不推荐用。于是我一般来说都是自己定义一个唯一的key,而不使用ftok函数。
阅读(1384) | 评论(0) | 转发(0) |