1. 使用shmget函数创建共享内存时,参数如果是IPC_PRIVATE,则共享内存的key值都一样,为0。
如果要使key非0,则需要借助函数ftok。
只要key值一样,用户空间的进程通过函数打开,就会对内核的同一个IPC对象进行操作。
2. ftok函数:
原型: char ftok(const char *path, char key)
参数: path:文件路劲和文件名
key:一个字符
返回值:成功返回一个key值
失败-1
3. 创建了共享内存后需要将内存映射到用户空间,减少内核访问,映射函数为shmat
原型:void *shmat(int shmid, const void *shmaddr, int shmflg) //类似于malloc
参数: 第一个参数,ID号
第二个参数,映射到的地址,NULL为系统自动完成的映射
第三个参数,shmflg, SHM_RDONLY共享内存只读
默认是0,表示可读写
返回: 成功映射后的地址
失败NULL
4. 共享内存的特点:
共享内存创建后一直存在于内核中,直到被删除或系统关闭;
共享内存和管道一样,读取后,内容仍然存在。
5. 实例一:通过a.c生成key值
#include "sys/types.h"
#include "sys/shm.h"
#include "signal.h"
#include "unistd.h"
#include "stdio.h"
#include "stdlib.h"
int main()
{
int shmid;
int key;
key=ftok("./a.c",'b');
if(key <0 )
{
printf("creat key fialure\n");
return -2;
}
printf("creat key sucess key=%X\n",key);
shmid=shmget(key,128,IPC_CREAT | 0777);
if(shmid <0)
{
printf("creat share memory failure\n");
return -1;
}
printf("creat share memory sucess shmid=%d\n",shmid);
system("ipcs -m");
// system("ipcrm -m shmid");
return 0;
}
执行结果:
alex@alex-virtual-machine:/extra/process/twelve$ ls a.c a.out shm_1.c shm_2.c alex@alex-virtual-machine:/extra/process/twelve$ ./a.out creat key sucess key=6211A066 creat share memory sucess shmid=2162699 ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x00000000 950272 alex 600 524288 2 dest 0x00000000 1867777 alex 600 524288 2 dest 0x00000000 425986 alex 600 524288 2 dest 0x00000000 458755 alex 600 524288 2 dest 0x00000000 2064388 alex 600 524288 2 dest 0x00000000 1572869 alex 600 33554432 2 dest 0x00000000 2129926 alex 777 128 0 0x00000000 1081351 alex 600 16777216 2 0x00000000 1179656 alex 600 524288 2 dest 0x00000000 2097161 alex 600 1048576 2 dest 0x00000000 1409034 alex 600 524288 2 dest 0x6211a066 2162699 alex 777 128 0 alex@alex-virtual-machine:/extra/process/twelve$
6.实例二,创建共享内存后,将其映射到用户空间,并对共享内存进行读写
执行结果:#include "sys/types.h" #include "sys/shm.h" #include "signal.h" #include "unistd.h" #include "stdio.h" #include "stdlib.h" int main() { int shmid; int key; char *p; key=ftok("./a.c",'b'); if(key <0 ) { printf("creat key fialure\n"); return -2; } printf("creat key sucess key=%X\n",key); shmid=shmget(key,128,IPC_CREAT | 0777); if(shmid <0) { printf("creat share memory failure\n"); return -1; } printf("creat share memory sucess shmid=%d\n",shmid); system("ipcs -m"); p=(char *)shmat(shmid,NULL,0); if(p == NULL) { printf("shmat function failure\n"); return -3; } //write share memory fgets(p,128,stdin); //start read share memory printf("share memory data:%s",p); printf("second read share memory data:%s",p); // system("ipcrm -m shmid"); return 0; }
alex@alex-virtual-machine:/extra/process/twelve$ gcc shm_2.c alex@alex-virtual-machine:/extra/process/twelve$ ls -lh total 16K -rwxrwxrwx 1 smbuser smbuser 0 11月 4 2015 a.c -rwxrwxr-x 1 alex alex 7.5K 1月 21 21:00 a.out -rwxrwxrwx 1 smbuser smbuser 533 11月 4 2015 shm_1.c -rwxrwxrwx 1 smbuser smbuser 810 11月 4 2015 shm_2.c alex@alex-virtual-machine:/extra/process/twelve$ ./a.out creat key sucess key=6211A066 creat share memory sucess shmid=2162699 ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x00000000 950272 alex 600 524288 2 dest 0x00000000 1867777 alex 600 524288 2 dest 0x00000000 425986 alex 600 524288 2 dest 0x00000000 458755 alex 600 524288 2 dest 0x00000000 2064388 alex 600 524288 2 dest 0x00000000 1572869 alex 600 33554432 2 dest 0x00000000 2129926 alex 777 128 0 0x00000000 1081351 alex 600 16777216 2 0x00000000 1179656 alex 600 524288 2 dest 0x00000000 2097161 alex 600 1048576 2 dest 0x00000000 1409034 alex 600 524288 2 dest 0x6211a066 2162699 alex 777 128 0 hello linux share memory data:hello linux second read share memory data:hello linux alex@alex-virtual-machine:/extra/process/twelve$