新手建立网站的步骤,温州网站建设最新报价,长春网站建设培训,wordpress 如何调试什么是共享内存#xff1f;
对于两个进程#xff0c;通过在内存开辟一块空间#xff08;操作系统开辟的#xff09;#xff0c;进程的虚拟地址通过页表映射到对应的共享内存空间中#xff0c;进而实现通信#xff1b;物理内存中的这块空间#xff0c;就叫做共享内存。…什么是共享内存
对于两个进程通过在内存开辟一块空间操作系统开辟的进程的虚拟地址通过页表映射到对应的共享内存空间中进而实现通信物理内存中的这块空间就叫做共享内存。 共享内存的优缺点 优点方便、接口简单、加快程序效率、不要求进程有“血缘”关系。 缺点没有提供同步机制需要借助其他手段进行进程间同步工作。 共享内存可以快于消息传递但有高速缓存一致性问题。 shmget函数 功能用来创建共享内存 参数 key_t key一个键值用于唯一标识一个共享内存段。由用户输入不能由内核自主生成。若由内核生成则会导致两个进程看不到同一块共享内存。你可以使用IPC_PRIVATE常量创建一个私有共享内存段或使用ftok()函数根据文件路径生成一个唯一的键值。 size_t size共享内存的大小以字节为单位。 int shmflg标志位用于控制创建和获取共享内存的行为。 IPC_CREAT若指定的共享内存不存在创建并返回若已存在获取并返回。 即保证调用进程能拿到共享内存。 IPC_CREAT | IPC_EXCL若共享内存不存在创建并返回若已存在出错并 返回。即只要成功拿到的一定是新的共享内存(不拿旧的) 返回值成功时返回共享内存的标识符一个非负整数失败时返回-1。 // Comm代码模块
const std::string gpath /home/ubuntu/112/linux/lesson24-fifo;
int gprojId 0x6666;
int gshmsize 4096;
// Server代码模块
int main()
{// 1. 创建keykey_t k ::ftok(gpath.c_str(), gprojId);if(k -1){ perror(ftok errror: );}std::cout k : ToHex(k) std::endl;// 2.创建共享内存 获取int shmid ::shmget(k, gshmsize, IPC_CREAT | IPC_EXCL);if(shmid 0){std::cerr shmget error std::endl;return 2;}std::cout shmid: std::endl;return 0;
} 共享内存的管理指令(指令释放)
ipcs 查询所有的system V通信方式 ipcs -m 查询共享内存
这里的key值与上面查询的是一样的。 ipcrm -m shmid删除共享内存 删除共享内存之后再运行server就成功了 shmid vs key shmid只给用户用的一个标识shm的标识符key只作为内核中区分shm唯一性的标识符不作为用户管理shm 的id值 共享内存的管理函数(代码释放)
shmctl函数 功能用于控制共享内存原型 参数 shmid由shmget返回的共享内存标识码 cmd将要采取的动作有三个可取值 buf指向⼀个保存着共享内存的模式状态和访问权限的数据结构 返回值成功返回0失败返回-1 在上面代码的基础上加上下面这句代码即可完成代码实现删除共享内存
shmctl(shmid, IPC_RMID, nullptr); ftok函数
在shmget函数中我们说到参数key是唯一的且是由用户输入的但是用户有没有可能设置的key有冲突呢答案是肯定的。所以基于这个问题我们引入了ftok函数。你只要给我一个公共的路径和一个公共的项目ID我就会依据算法生成一个唯一值。虽然这样也有可能造成冲突但是冲突的几率特别特别小
// Comm模块代码
const std::string gpath /home/ubuntu/112/linux/lesson24-fifo;
int projId 0x6666;
// Client / Server模块代码
#include iostream
#include Comm.hpp
int main()
{key_t k ::ftok(path.c_str(), projId);if(k 0){std::cerr ftok error std::endl;return 1;}std::cout k: k std::endl; return 0;
} 如果ftok函数返回失败时我们就需要不断的尝试对路径名和id值进行修改直至成功。一般来说有几种可能 如果传入的路径名不存在传入的路径名没有读取权限无法读取该文件的索引节点号文件的索引节点超过了8位即超过了一个字节的范围系统中已经使用了所有的IPC键值 shmat函数 功能将共享内存段连接到进程地址空间原型(关联) 参数 shmid共享内存标识 shmaddr指定连接的地址 shmflg是一组按位OR或在一起的标志用来控制读写权限等。它的两个可能取值是SHM_RND和SHM_RDONLY。若取值为SHM_RDONLY则以只读方式连接此段否则以读写的方式连接此段。 返回值成功返回一个指向共享内存起始地址的指针失败返回-1 说明 shmaddr为NULL核心自动选择一个地址shmaddr不为NULL且shmflg无SHM_RND标记则以shmaddr为连接地址。shmaddr不为NULL且shmflg设置了SHM_RND标记则连接的地址会自动向下调整为SHMLBA的整数倍。公式shmaddr - (shmaddr % SHMLBA)shmflg SHM_RDONLY表示连接操作用来只读共享内存 void* ret shmat(shmid, nullptr, 0);// 将共享内存挂接到自己的地址空间中 注意共享内存也有权限
shmdt函数 功能将共享内存段与当前进程脱离原型(去关联) 参数 shmaddr: 由shmat所返回的指针 返回值成功返回0失败返回-1 注意将共享内存段与当前进程脱离不等于删除共享内存段 ::shmdt(ret); // 去关联
shmdt的参数就是shmat的返回值。
共享内存的特点
优点 高效性 共享内存是IPC通信中传输速度最快的通信方式。因为数据不需要在客户机和服务器之间拷贝数据可以直接写到内存避免了多次数据拷贝从而大大提高了通信效率。进程对共享内存的访问就如同访问自己的内存空间一样不需要进行额外的系统调用或内核操作进一步提升了效率。 灵活性 允许多个进程共享数据提供了一种灵活的通信方式。进程间可以通过共享的内存区域进行双向通信满足了多种通信需求。 支持大量数据传输 适用于需要快速传递大量数据的场景特别是在大数据处理、实时通信等领域表现突出。 缺点 具有同步相关的问题 因为多个进程可以同时访问共享内存因此需要额外的同步机制来避免 数据不一致性 问题。内核中并不提供任何对共享内存访问的同步机制因此通常需要使用信号量等其他IPC机制进行读写同步与互斥。例写端要向共享内存中写入hello world但只写了hello读端就读走了 安全性 需要额外的安全机制来保护数据防止其他进程非法访问。若未采取适当的安全措施可能导致数据泄露或被篡改。 编程复杂性 使用共享内存进行通信需要处理同步和数据一致性等复杂问题编程复杂度较高。需要开发者具备深厚的操作系统和并发编程知识。 依赖操作系统支持 共享内存的使用依赖于操作系统的支持。不同的操作系统或版本可能对共享内存的实现和管理方式存在差异这增加了跨平台开发的难度。