旅游集团网站建设,河南省建设厅网站人事网,wordpress调整语言,在线广告平面设计定义#xff1a; 共享内存允许两个或者多个进程共享物理内存的同一块区域#xff08;通常被称为段#xff09;。由于一个共享内存段会称为一个进程用户空间的一部分#xff0c;因此这种 IPC 机制无需内核介入。所有需要做的就是让一个进程将数 据复制进共享内存中#xff…定义 共享内存允许两个或者多个进程共享物理内存的同一块区域通常被称为段。由于一个共享内存段会称为一个进程用户空间的一部分因此这种 IPC 机制无需内核介入。所有需要做的就是让一个进程将数 据复制进共享内存中并且这部分数据会对其他所有共享同一个段的进程可用。 与管道等要求发送进程将数据从用户空间的缓冲区复制进内核内存和接收进程将数据从内核内存复制进用户空间的缓冲区的做法相比这种 IPC 技术的速度更快。 使用步骤 1. 调用 shmget() 创建一个新共享内存段或取得一个既有共享内存段的标识符即由其他进程创建的共享内存段。这个调用将返回后续调用中需要用到的共享内存标识符。 2. 使用 shmat() 来附上共享内存段即使该段成为调用进程的虚拟内存的一部分。 此刻在程序中可以像对待其他可用内存那样对待这个共享内存段。为引用这块共享内存程序需要 3. 使用由 shmat() 调用返回的 addr 值它是一个指向进程的虚拟地址空间中该共享内存段的起点的指针。 4. 调用 shmdt() 来分离共享内存段。在这个调用之后进程就无法再引用这块共享内存了。这一步是 可选的并且在进程终止时会自动完成这一步。 5. 调用 shmctl() 来删除共享内存段(前面的分离操作只是这个进程不能使用共享内存但是这块共享内存仍然存在)。只有当当前所有附加内存段的进程都与之分离之后内存段才会销毁。只有一个进程需要执行这一步。(当还有进程共享内存时删除共享内存段是不会成功的。因为还有别的进程在使用共享内存段。) 相关函数 shmget() #include sys/ipc.h
#include sys/shm.hint shmget(key_t key, size_t size, int shmflg);- 功能创建一个新的共享内存段或者获取一个既有的共享内存段的标识。新创建的内存段中的数据都会被初始化为0- 参数- key : key_t类型是一个整形通过这个找到或者创建一个共享内存。一般使用16进制表示非0值- size: 共享内存的大小(以分页的大小去创建的也就是第一个大于传入的大小的分页大小去创建)- shmflg: 属性- 访问权限- 附加属性创建/判断共享内存是不是存在- 创建IPC_CREATIPC_CREAT 是一个用于创建共享内存的标志指定了共享内存的权限。如果共享内存已经存在该标志会被忽略。- 判断共享内存是否存在 IPC_EXCL , 需要和IPC_CREAT一起使用使用例子IPC_CREAT | IPC_EXCL | 0664- 返回值失败-1 并设置错误号成功 0 返回共享内存的引用的ID后面操作共享内存都是通过这个值。shmat(): #include sys/ipc.h
#include sys/shm.hvoid *shmat(int shmid, const void *shmaddr, int shmflg);- 功能和当前的进程进行关联- 参数- shmid : 共享内存的标识ID,由shmget返回值获取- shmaddr: 申请的共享内存的起始地址(虚拟内存当中的地址)指定NULL内核指定- shmflg : 对共享内存的操作- 读 SHM_RDONLY, 必须要有读权限- 读写 0 (必须要有读权限和写权限才能去操作共享内存)- 返回值成功返回共享内存的首起始地址。 失败(void *) -1 shmdt() #include sys/ipc.h
#include sys/shm.hint shmdt(const void *shmaddr);- 功能解除当前进程和共享内存的关联- 参数shmaddr共享内存的首地址- 返回值成功 0 失败 -1 shmctl() #include sys/ipc.h
#include sys/shm.hint shmctl(int shmid, int cmd, struct shmid_ds *buf);- 功能对共享内存进行操作。主要用来删除共享内存共享内存要删除才会消失创建共享内存的进行被销毁了对共享内存是没有任何影响。- 参数- shmid: 共享内存的ID- cmd : 要做的操作- IPC_STAT : 获取共享内存的当前的状态- IPC_SET : 设置共享内存的状态- IPC_RMID: 标记共享内存被销毁- buf需要设置或者获取的共享内存的属性信息- IPC_STAT : buf存储数据- IPC_SET : buf中需要初始化数据设置到内核中- IPC_RMID : 没有用NULLkey_t ftok() #include sys/ipc.h
#include sys/shm.hkey_t ftok(const char *pathname, int proj_id);- 功能根据指定的路径名和int值生成一个共享内存的key- 参数- pathname:指定一个存在的路径/home/nowcoder/Linux/a.txt/ - proj_id: int类型的值但是这系统调用只会使用其中的1个字节范围 0-255 一般指定一个字符 a使用共享内存实现简单的通信 写程序代码如下 #include stdio.h
#include sys/ipc.h
#include sys/shm.h
#include string.hint main() { // 1.创建一个共享内存int shmid shmget(100, 4096, IPC_CREAT | 0664);// 第一个参数一般给16进制的数printf(shmid : %d\n, shmid);// 2.和当前进程进行关联void * ptr shmat(shmid, NULL, 0);char * str helloworld;// 3.写数据memcpy(ptr, str, strlen(str) 1);printf(按任意键继续\n);// 不加程序会直接解除关联getchar();// 4.解除关联shmdt(ptr);// 5.删除共享内存shmctl(shmid, IPC_RMID, NULL);return 0;
} 读程序代码如下 #include stdio.h
#include sys/ipc.h
#include sys/shm.h
#include string.hint main() { // 1.获取一个共享内存int shmid shmget(100, 0, IPC_CREAT);// 注意不能大于写文件的4096大小这里也可以填4096。一般填0表示获取一个共享内存printf(shmid : %d\n, shmid);// 2.和当前进程进行关联void * ptr shmat(shmid, NULL, 0);// 3.读数据printf(%s\n, (char *)ptr);printf(按任意键继续\n);getchar();// 4.解除关联shmdt(ptr);// 5.删除共享内存shmctl(shmid, IPC_RMID, NULL);return 0;
} 运行结果如下 操作命令
ipcs 用法 1. ipcs -a // 打印当前系统中所有的进程间通信方式的信息 2. ipcs -m // 打印出使用共享内存进行进程间通信的信息 3. ipcs -q // 打印出使用消息队列进行进程间通信的信息 4. ipcs -s // 打印出使用信号进行进程间通信的信息 ipcrm 用法 1. ipcrm -M shmkey // 移除用 shmkey 创建的共享内存段 2. ipcrm -m shmid // 移除用 shmid 标识的共享内存段 3. ipcrm -Q msgkey // 移除用 msqkey 创建的消息队列 4. ipcrm -q msqid // 移除用 msqid 标识的消息队列 5. ipcrm -S semkey // 移除用 semkey 创建的信号 6. ipcrm -s semid // 移除用 semid 标识的信号 一些需要注意的细节
问题1操作系统如何知道一块共享内存被多少个进程关联- 共享内存维护了一个结构体struct shmid_ds 这个结构体中有一个成员 shm_nattch- shm_nattach 记录了关联的进程个数问题2可不可以对共享内存进行多次删除 shmctl- 可以的- 因为shmctl 标记删除共享内存不是直接删除- 什么时候真正删除呢?当和共享内存关联的进程数为0的时候就真正被删除- 当共享内存的key为0的时候表示共享内存被标记删除了如果一个进程和共享内存取消关联那么这个进程就不能继续操作这个共享内存。也不能进行关联。 共享内存和内存映射的区别
1.共享内存可以直接创建内存映射需要磁盘文件匿名映射除外2.共享内存效率更高3.内存所有的进程操作的是同一块共享内存。内存映射每个进程在自己的虚拟地址空间中有一个独立的内存。4.数据安全- 进程突然退出共享内存还存在内存映射区消失- 运行进程的电脑死机宕机了数据存在在共享内存中没有了内存映射区的数据 由于磁盘文件中的数据还在所以内存映射区的数据还存在。5.生命周期- 内存映射区进程退出内存映射区销毁- 共享内存进程退出共享内存还在标记删除所有的关联的进程数为0或者关机如果一个进程退出会自动和共享内存进行取消关联。