ipc 共享内存 shared memmory
2014-11-01 14:06
267 查看
下面两篇博客对ipc shares memory 讲述的比较清晰
1.http://blog.chinaunix.net/uid-26833883-id-3230564.html
2.http://blog.csdn.net/ljianhui/article/details/10253345
共享内存(shared memory)是最简单的Linux进程间通信方式之一。使用共享内存,不同进程可以对同一块内存进行读写。由于所有进程对共享内存的访问就和访问自己的内存空间一样,而不需要进行额外系统调用或内核操作,同时还避免了多余的内存拷贝,所以,这种方式是效率最高、速度最快的进程间通信方式。
这种最大限度的自由也给共享内存带来了缺点:内核并不提供任何对共享内存访问的同步机制,比如同时对共享内存的相同地址进行写操作,则后写的数据会覆盖之前的数据。所以,使用共享内存一般还需要使用其他IPC机制(如信号量)进行读写同步与互斥。
基本原理
了解Linux内存管理机制,就很容易知道共享内存的原理了。大家知道,内核对内存的管理是以页(page)为单位的,Linux下一般一个page大小是4k。而程序本身的虚拟地址空间是线性的,所以内核管理了进程从虚拟地址空间到起对应的页的映射。创建共享内存空间后,内核将不同进程虚拟地址的映射到同一个页面:所以在不同进程中,对共享内存所在的内存地址的访问最终都被映射到同一页面。下图演示了共享内存的工作机制:
![](http://hi.csdn.net/attachment/201108/19/0_1313742359TTw7.gif)
代码如下:
同时linux shell通过命令ipcs ipcrm分别对进程通信进行创建删除显示信息等操作
1.http://blog.chinaunix.net/uid-26833883-id-3230564.html
2.http://blog.csdn.net/ljianhui/article/details/10253345
共享内存(shared memory)是最简单的Linux进程间通信方式之一。使用共享内存,不同进程可以对同一块内存进行读写。由于所有进程对共享内存的访问就和访问自己的内存空间一样,而不需要进行额外系统调用或内核操作,同时还避免了多余的内存拷贝,所以,这种方式是效率最高、速度最快的进程间通信方式。
这种最大限度的自由也给共享内存带来了缺点:内核并不提供任何对共享内存访问的同步机制,比如同时对共享内存的相同地址进行写操作,则后写的数据会覆盖之前的数据。所以,使用共享内存一般还需要使用其他IPC机制(如信号量)进行读写同步与互斥。
基本原理
了解Linux内存管理机制,就很容易知道共享内存的原理了。大家知道,内核对内存的管理是以页(page)为单位的,Linux下一般一个page大小是4k。而程序本身的虚拟地址空间是线性的,所以内核管理了进程从虚拟地址空间到起对应的页的映射。创建共享内存空间后,内核将不同进程虚拟地址的映射到同一个页面:所以在不同进程中,对共享内存所在的内存地址的访问最终都被映射到同一页面。下图演示了共享内存的工作机制:
![](http://hi.csdn.net/attachment/201108/19/0_1313742359TTw7.gif)
代码如下:
#include <sys/shm.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <semaphore.h> #include <fcntl.h> #include <sys/stat.h> #define BUFF_SIZE 1024 int father_do_work(int shmid) { char *buf; void *shmaddr; sem_t *prsem; sem_t *pwsem; //有名信号量 if((prsem = sem_open("rsem",O_CREAT,0666,0)) == SEM_FAILED) { perror("Fail to sem open"); return -1; } //有名信号量 if((pwsem = sem_open("wsem",O_CREAT,0666,1)) == SEM_FAILED) { perror("Fail to sem open"); return -1; } //映射共享内存 if((shmaddr = shmat(shmid,NULL,0)) == (void *)-1) { perror("Fail to shmat"); exit(EXIT_FAILURE); } buf = (char *)shmaddr; while(1) { if(sem_wait(pwsem) < 0) { perror("Fail to sem wait"); break; } printf(">"); fgets(buf,BUFF_SIZE,stdin); buf[strlen(buf) - 1] = '\0'; if(sem_post(prsem) < 0) { perror("Fail to sem post"); break; } if(strncmp(buf,"quit",4) == 0) { if(shmdt(shmaddr) < 0) { perror("Fail to shmaddr"); exit(EXIT_FAILURE); } break; } usleep(500); } return 0; } int child_do_work(int shmid) { char *buf; void *shmaddr; sem_t *prsem; sem_t *pwsem; // if((prsem = sem_open("rsem",O_CREAT,0666,0)) == SEM_FAILED) { perror("Fail to sem open"); return -1; } if((pwsem = sem_open("wsem",O_CREAT,0666,1)) == SEM_FAILED) { perror("Fail to sem open"); return -1; } //映射共享内存 if((shmaddr = shmat(shmid,NULL,0)) == (void *)-1) { perror("Fail to shmat"); exit(EXIT_FAILURE); } buf = (char *)shmaddr; while(1) { if(sem_wait(prsem) < 0) { perror("Fail to prsem"); break; } printf("read buf : %s.\n",buf); if(sem_post(pwsem) < 0) { perror("Fail to pwsem"); break; } if(strncmp(buf,"quit",4) == 0) { if(shmdt(shmaddr) < 0) { perror("Fail to shmaddr"); exit(EXIT_FAILURE); } break; } } return 0; } int main() { int shmid; int pid; void *shmaddr; //创建共享内存 if((shmid = shmget((key_t)16,BUFF_SIZE,0666 | IPC_CREAT)) < 0) { perror("Fail to shmget"); exit(EXIT_FAILURE); } if((pid = fork()) < 0) { perror("Fail to fork"); exit(EXIT_FAILURE); }else if(pid == 0){ child_do_work(shmid); }else{ father_do_work(shmid); wait(NULL); if(shmctl(shmid,IPC_RMID,NULL) < 0) { perror("Fail to shmctl"); exit(EXIT_FAILURE); } } exit(EXIT_SUCCESS); }
同时linux shell通过命令ipcs ipcrm分别对进程通信进行创建删除显示信息等操作
相关文章推荐
- 多线程进程间通讯共享内存(Shared Memory with IPC with threads)
- 细说linux IPC(三):mmap系统调用共享内存
- IPC之共享内存
- Linux C编程--进程间通信(IPC)5--System V IPC 机制3--共享内存
- Linux IPC之共享内存
- Linux进程间通信(IPC)编程实践(六)共享内存的使用-mmap
- 阐述linux IPC(五岁以下儿童):system V共享内存
- IPC共享内存
- 进程间通信总结 && IPC主题三之 共享内存
- Linux编程实践----共享内存的演示(IPC)
- Linux C 进程间的IPC通信 之 共享内存(一)
- IPC最快的方式----共享内存(shared memory)
- 进程间通信(IPC)之————共享内存
- 细说linux IPC(四):posix 共享内存
- IPC编程之共享内存
- linux进程通信IPC之共享内存的IPC_PRIVATE与ftok比较
- 细说linux IPC(四):posix 共享内存
- Linux C编程--进程间通信(IPC)6--综合应用实例--信号量和共享内存的使用
- 进程间通信IPC——共享内存
- IPC通信之共享内存