标签:
关于内存共享的几个函数
1.用来创建一个共享内存
int shmget(key_t key, size_t size, int shmflg);
key:这个共享内存的段的名字
size:共享内存的大小
shmflg:由九个权限标志构成,它们的用法和穿件文件时使用的mode权限一样
成功返回非负整数,即该内存共享端的标识码;失败返回-1;
int main(int argc, const char *argv[]) { int shmid; shmid = shmget(1234, sizeof(STU), IPC_CREAT | 0666); if(shmid == -1) ERR_EXIT("shmget"); return 0; }
这样就可以简单的创建一个共享内存, 1234是它的id,sizeof(STU)是它的大小。
内存id是我们自己取的。只要不重复就是可以成功创建的,如果id1234的共享内存存在,创建便会失败
返回值为-1;
2.shmat函数将共享内存段连接到进程地址空间
原型 void *shmat(int shmid, const void *shmaddr, int shmflg);
shmid:共享内存标示
shmaddr:指定连接的地址
shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY
返回值:成功返回一个指针,指向共享内存的第一个字节,失败返回-1;
##通常我们推荐shmaddr为NULL,核心自动选择一个地址。
##shmaddr不为NULL且shmflg无SHM_RND标记,则以shmaddr为连接地址
##shmaddr不为NULL且shmflg设置了SHM_RND标记,则连接的地址会自动向下调整为
SHMLBA的整数倍,公式shmaddr-(shmaddr%SHMLBA);
##shmflg = SHM_RDONLY,表示连接操作用来只读共享内存。
3.shmctl函数
用来控制共享内存,在内核层面进行控制
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
shmid:标识码
cmd:将要采取的动作,有三个取值
buf:指向一个保存着共享内存的模式状态和访问权限的数据结构
返回值:成功返回0,失败返回-1;
下面贴上创建共享内存,在读取后删除的的代码。
#include <unistd.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/shm.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define ERR_EXIT(m) do { perror(m); exit(EXIT_FAILURE); }while(0) typedef struct stu { char name[4]; int age; }STU; int main(int argc, const char *argv[]) { int shmid; shmid = shmget(1234, sizeof(STU), IPC_CREAT | 0666); if(shmid == -1) ERR_EXIT("shmget"); STU *p; p = shmat(shmid, NULL, 0); if(p == (void*)-1) ERR_EXIT("shmat"); strcpy(p->name, "lisi"); p->age = 20; sleep(10); shmdt(p); return 0; }
读取后删除
#include <unistd.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/shm.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define ERR_EXIT(m) do { perror(m); exit(EXIT_FAILURE); }while(0) typedef struct stu { char name[4]; int age; }STU; int main(int argc, const char *argv[]) { int shmid; shmid = shmget(1234, 0, 0); if(shmid == -1) ERR_EXIT("shmget"); STU *p; p = shmat(shmid, NULL, 0); if(p == (void*)-1) ERR_EXIT("shmat"); printf("name = %s age = %d\n", p->name, p->age); shmdt(p); shmctl(shmid, IPC_RMID, NULL); return 0; }
shmdt只是断开连接,并没有在内核中删除共享内存。
所以必须手动调用shmctl去内核中删除,在ipcs查看。
标签:
原文地址:http://www.cnblogs.com/DLzhang/p/4332237.html