共享内存

来源:互联网 发布:有关c语言的书籍 编辑:程序博客网 时间:2024/05/16 12:07

什么是共享内存?

   共享内存顾名思义就是允许两个不相关的进程访问同一个逻辑内存。共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常安排为同一段物理内存。进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言函数malloc分配的内存一样。而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程。

代码

#ifndef _SHM_#define _SHM_#include <stdio.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/wait.h>#include <unistd.h>#define _PATH_ "."#define _PROJECT_ 8888#define _SHM_SIZE_ 4*1024int get_shm();char *at_shm();int delete_shm();int rm_shm();#endif
#include "shm.h"int get_shm(){    key_t key = ftok(_PATH_,_PROJECT_);    int flag = IPC_CREAT | 0666;    int shm_id = shmget(key,_SHM_SIZE_,flag);    if(shm_id ==-1)    {        printf("shmget error\n");    }    else    {        printf("shmget success\n");    }    return shm_id;}char *at_shm(int shm_id){    return (char*)shmat(shm_id,NULL,0);}int delete_shm(char* addr){    return shmdt(addr);}int rm_shm(int shm_id){    return shmctl(shm_id,IPC_RMID,NULL);}int main(){    int shm_id = get_shm();    //创建新进程    pid_t id= fork();    if(id<0)    {        printf("fork error\n");        return 1;    }else if(id==0)    {//child    char *buf = at_shm(shm_id);    int i = 0;      while(i<4096)     {     buf[i]= 'w';        i++;      }    buf[4096]= '\0';   delete_shm(buf);    }else    {//father   char *buf = at_shm(shm_id);     sleep(3);     printf("%s\n",buf);     waitpid(id,NULL,0);     rm_shm(shm_id);    }    return 0;}

共享内存的特点:

    共享内存分为两种:一种是POSIX的共享内存,通过用户空间挂载的tmpfs文件系统实现的。(上层不会在意你是内核还是用户空间来实现的)。另一种是system V的共享内存是由内核本身的tmpfs实现的。(严格由操作系统内核提供接口和实现。)    posix的共享内存机制实际上在库过程中以及用户空间的其他部分被展示为完全的文件系统的调用过程,在调用完shm_open之后,需要调用mmap来将tmpfs的文件映射到地址空间,接着就可以操作这个文件了,需要注意的是,别的进程也可以操作这个文件,因此这个文件其实就是共享内存。     而system v的共享内存,内核直接实现了shmget/at系统调用,虽然最终也是靠tmpfs来实现的,但是接口设计上和posix完全不同,posix旨在提供所有系统都一致的接口,而system v只在于实现自己的逻辑,共享内存其实只是sysv中ipc的一部分,最终的管理数据结构也是ipc的而不是共享内存的。    共享内存是所有进程间通信速度最快的,而且它的生命周期随内核。

共享内存优缺点

    优点:采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝。对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次数据[1]: 一次从输入文件到共享内存区,另一次从共享内存区到输出文件。实际上,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时,再重新建 立共享内存区域。而是保持共享区域,直到通信完毕为止,这样,数据内容一直保存在共享内存中,并没有写回文件。共享内存中的内容往往是在解除映射时才写回 文件的。因此,采用共享内存的通信方式效率是非常高的。    缺点: 共享内存没有提供同步的机制,这使得我们在使用共享内存进行进程间通信时,往往要借助其他的手段(信号量)来进行进程间的同步工作。
原创粉丝点击