广州做网站开发,军事网报名入口,wordpress自定义属性,专业网站快速排名优势一、基本概念 什么是共享内存#xff0c;顾名思义#xff0c;就是将共享一片内存空间#xff0c;共享内存允许多个不同的进程访问同一片内存空间。他们对这个内存直接进行操作#xff0c;不需要经过内核的处理#xff0c;因此共享内存是IPC通信方式中效率最高的。那如何实…一、基本概念 什么是共享内存顾名思义就是将共享一片内存空间共享内存允许多个不同的进程访问同一片内存空间。他们对这个内存直接进行操作不需要经过内核的处理因此共享内存是IPC通信方式中效率最高的。那如何实现的呢只要你想访问这片内存空间你得先把这片内存空间映射到你的内存中然后再对其进行操作。 但是这种内存空间我们要对其进行维护保护的一个操作例如进程A往共享内存存数据而此时进程B刚好在读数据那B读取的数据就可能会出现数据混乱因此共享内存属于临界资源我们在操作它时要进行保护操作即在某一个时刻只有一个进程对其进行读/写操作防止数据出现混乱。所以共享内存一般不会单独的进行使用要配合信号量、互斥锁等来进行使用目的就是保护数据的完整性。 特点1共享内存是进程间通信效率最高的方式之一 2共享内存可传输的数据量比较大使用共享内存一般是以传输数据为目的的 3读取过的内容不会删除某一个进程修改共享内存空间的数据后其他进程可以察觉这个修改 4无同步无互斥需要信号量配合。
二、基本使用流程 1创建或获取共享内存 int shmget(key_t key, size_t size, int shmflg); key的取值 ① 通过调用key_t ftok(const char *pathname, int proj_id)来进行获取;这个函数是通过指定的文件路径和计划编号合成一个key值。 ② IPC_PRIVATE 内核会保证创建一个新的唯一的IPC对象这是一个宏定义其值为0。 size指定共享内存的大小是以页为单位的即使存1个字节也会分配一整页。 shmflgIPC_CREAT 若系统中有相同的key值则返回共享内存的标识符若不存在则创建要与 0600 结合 给相应的权限IPC_CREAT | 0600。 IPC_EXCL 如果系统中有相同的key值则会报错不存在则创建。 2将共享内存映射到当前进程中 void *shmat(int shmid, const void *shmaddr, int shmflg); shmid就是创建共享内存时返回的描述符。 shmaddr一般为NULL系统会帮你自动选择一个内存空间去分配。 shmflg操作共享内存的方式 SHM_RDONLY以只读方式打开。 SHM_EXEC具有执行的权限。 SHM_REMAP:重新映射此时shmaddr不能为空。 3操作共享内存 直接针对映射后返回的指针进行操作给指针进行赋值。 4断开共享内存映射 int shmdt(const void *shmaddr); shmaddr映射的共享内存的地址。 成功返回0失败返回-1并将错误记录。 5释放共享内存 int shmctl(int shmid, int cmd, struct shmid_ds *buf); shmid共享内存的标识符 cmd常用的控制命令如下 IPC_RMID删除该共享内存 IPC_STAT获取属性权限放到buf中 IPC_SET设置属性信息为buf指向的内容。 IPC_INFO获得关于共享内存的系统限制值信息。 SHM_INFO获得系统为共享内存消耗的资源信息。 buf在释放共享内存时为NULL即可。
struct shmid_ds {struct ipc_perm shm_perm; /* Ownership and permissions */size_t shm_segsz; /* Size of segment (bytes) */time_t shm_atime; /* Last attach time */time_t shm_dtime; /* Last detach time */time_t shm_ctime; /* Last change time */pid_t shm_cpid; /* PID of creator */pid_t shm_lpid; /* PID of last shmat(2)/shmdt(2) */shmatt_t shm_nattch; /* No. of current attaches */...};
struct ipc_perm {key_t __key; /* Key supplied to shmget(2) */uid_t uid; /* Effective UID of owner */gid_t gid; /* Effective GID of owner */uid_t cuid; /* Effective UID of creator */gid_t cgid; /* Effective GID of creator */unsigned short mode; /* Permissions SHM_DEST andSHM_LOCKED flags */unsigned short __seq; /* Sequence number */};
三、代码示例 一个进程负责读取你的个人信息并写入到共享内存另一个进程负责将共享内存中的个人信息进行打印 #include stdio.h
#include sys/types.h
#include sys/stat.h
#include sys/ipc.h
#include sys/shm.h
#include string.h
#include stdlib.h
#include unistd.h
#include wait.hstruct info
{char name[50];int age;char address[100];
}DATA;int main()
{struct info data {zhangsan,22,xian};key_t key ftok(/bin/bash,1);if(key -1){perror(failed1);return -1;}//创建一个共享内存int shmid shmget(key,sizeof(struct info),IPC_CREAT | 0600);if(shmid -1){perror(failed2);return -1;}//进行共享内存的映射char * buf (char*)shmat(shmid,NULL,0);if(*(int*)buf -1 ){perror(failed3);return -2;}pid_t pid fork();//子进程负责读共享内存的数据并打印if(pid 0){sleep(3);printf(%s\n,buf);shmdt(buf);exit(0);}//父进程往共享内存中写入数据else if(pid 0){char arr[5] ; snprintf(arr,sizeof(arr),%d,data.age);snprintf(buf,sizeof(struct info),%s %s %s,data.name,arr,data.address);wait(NULL);//等待子进程结束shmdt(buf);//关闭内存映射shmctl(shmid,IPC_RMID,NULL);//释放内存资源}return 0;
}