为了在多个进程间交换数据,内核专门留出了一块共享内存区域,所有需要访问该共享区域的进程都要把这共享区域映射到本进程的地址空间中。每个内存区域都有一个标示符(shmid),进程可以通过这个标示符访问内存区域。
共享内存通过shmget()获得或创建一个IPC共享内存区域,并返回相应的标示符。然后调用系统调用shmat()完成将该共享内存区域映射到进程地址空间。
1、函数接口
参考:
http://blog.chinaunix.net/uid-25272011-id-3157708.html2、给出实例以及运行结果:
write.c
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <stdio.h>
- #include <errno.h>
- #include <stdlib.h>
- #include <sys/shm.h>
- #include <string.h>
- #define MEM_SIZE 4096
- //首先创建共享内存,并写入数据:(将struct People data[4]中的数据写入创建的共享内存)
- //编译运行后,可用Shell命令ipcs -m查看,删除可用ipcrm -m (shmid号)。
- struct People{
- char name[20];
- char age;
- };
- int main()
- {
- int i;
- key_t key;
- char *pathname="./ftok.txt";
- int proj_id=5;
- int shm_id;
- struct People *shm_addr;
- struct People data[4]={
- {"name1",21},{"name2",22},{"name3",23},{"name4",24}
- };
- if ((key=ftok(pathname,proj_id))==-1){
- perror("ftok");
- exit(-1);
- }
- else{
- printf("ftok success! key=%d\n",key);
- }
- if((shm_id=shmget(key,MEM_SIZE,IPC_EXCL|IPC_CREAT|0600))==-1){
- perror("shmget");
- exit(-1);
- }
- else{
- printf("shmget success! shm_id=%d\n",shm_id);
- }
- if((shm_addr=shmat(shm_id,0,0))==(void *)-1){
- perror("shmat");
- exit(-1);
- }
- else{
- printf("shmat success!shm_addr=%p\n",shm_addr);
- }
- printf("start copy data to memory\n");
- memcpy((void *)shm_addr,(void *)data,sizeof(data));
- printf("copy over\n");
- for(i=0;i<4;i++){
- printf("name:%s\t",shm_addr[i].name);
- printf("age=%d\n",shm_addr[i].age);
- }
- if(shmdt(shm_addr)==-1){
- perror("shmdt");
- exit(-1);
- }
- else{
- printf("shmdt success!\n");
- }
- return 0;
- }
read.c
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <stdio.h>
- #include <errno.h>
- #include <stdlib.h>
- #include <sys/shm.h>
- #include <string.h>
- #define MEM_SIZE 4096
- //读出共享内存中的数据,并接删除共享内存:
- //编译运行后,再次用Shell命令ipcs -m查看,就没有创建的共享内存了。
- struct People{
- char name[20];
- char age;
- };
- int main()
- {
- int i;
- key_t key;
- char *pathname="./ftok.txt";
- int proj_id=5;
- int shm_id;
- struct People *shm_addr;
- if ((key=ftok(pathname,proj_id))==-1){
- perror("ftok");
- exit(-1);
- }
- else{
- printf("ftok success! key=%d\n",key);
- }
- if((shm_id=shmget(key,MEM_SIZE,0600))==-1){
- perror("shmget");
- exit(-1);
- }
- else{
- printf("shmget success! shm_id=%d\n",shm_id);
- }
- if((shm_addr=shmat(shm_id,0,0))==(void *)-1){
- perror("shmat");
- exit(-1);
- }
- else{
- printf("shmat success!shm_addr=%p\n",shm_addr);
- }
- for(i=0;i<4;i++){
- printf("name:%s\t",shm_addr[i].name);
- printf("age=%d\n",shm_addr[i].age);
- }
- if(shmdt(shm_addr)==-1){
- perror("shmdt");
- exit(-1);
- }
- else{
- printf("shmdt success!\n");
- }
- if(shmctl(shm_id,IPC_RMID,0)==-1){ //这边才是删除那块共享缓冲区
- perror("shmctl");
- exit(-1);
- }
- else{
- printf("shmctl success!\n");
- }
- return 0;
- }
详细的运行结果:本文的源代码参考自:
http://waiter94.blog.163.com/blog/static/5277376920100213456475/?fromdm&fromSearch&isFromSearchEngine=yes
阅读(1114) | 评论(0) | 转发(0) |