我带着小伙伴们学习了共享内存相关的内容。首先简单介绍共享内存,然后学习结构和功能,最后通过代码使用这些功能来使用共享内存。希望对大家有所帮助!1共享内存的概念及使用过程1)共享内存的概念共享内存是IPC机制之一。共享内存:允许两个或多个进程共享给定的内存区域。2)进程使用共享内存①进程1创建共享内存,然后映射共享内存。②进程2获取共享内存并映射共享内存。③交互完成,进程1分离共享内存,进程2分离共享内存。④进程1删除共享内存。2共享内存相关的结构体和函数0)共享内存相关的结构体内核为每个共享内存段维护一个结构体,每个共享内存段至少要包含以下成员。structshmid_ds{structipc_permshm_perm;//操作权限size_tshm_segsz;//段的大小(字节)time_tshm_atime;//最后一个进程附加到段的时间time_tshm_dtime;//最后一个进程离开段的时间time_tshm_ctime;//最后一个进程修改这个段的时间pid_tshm_cpid;//创建这个段进程的PIDpid_tshm_lpid;//最后一个shmat(2)/shmdt(2)的PIDshmatt_tshm_nattch;//当前附加到这个的进程数部分。..};系统为每个IPC对象保存了一个ipc_perm结构体,它描述了IPC对象的权限和所有者,每个版本的内核都有不同的ipc_perm结构体成员。structipc_perm{key_t__key;//为shmget(2)调用提供的键值uid_tuid;//共享内存所有者的有效用户UIDgid_tgid;//共享内存所有者组的有效组GIDuid_tcuid;//有效共享内存创建者用户UIDgid_tcgid;//共享内存创建者所属组的有效组IDUnsignedshortmode;//Privilege+SHM_DESTandSHM_LOCKEDflagunsignedshort__seq;//序号};1)shmget函数shmget函数用于创建或获取共享内存并返回其描述字符id。①函数原型。intshmget(key_tkey,size_tsizie,intshmflg)②头文件。include包括③参数。key:共享内存的键值。size:共享内存的大小。shmflg:开启标志,如果使用IPC_CREAT,会创建新的共享内存。④返回值。成功:返回创建或获取共享内存的描述符。失败:-1。2)shmat函数shmat函数用于映射共享内存,即将一个进程附加到它的地址空间。①函数原型。void*shmat(intshmid,constvoid*shmaddr,intshmflg)②头文件。includeinclude③参数。shmid:要映射的共享内存的描述符。shmaddr:共享内存的地址。shmflg:开启标志,如果使用IPC_CREAT,会创建新的共享内存。④返回值。成功:返回创建或获取共享内存的描述符。失败:-1。3)shmdt函数shmdt函数用于分离共享内存,即操作存储段后,使用该函数将进程与存储段分离,即断开与共享内存的连接。①函数原型。intshmdt(constvoid*shmaddr)②头文件。#include#include③参数。shmaddr:要断开连接的共享内存的映射地址。④返回值。成功:0。失败:-1。4)shmctl函数shmctl函数用于控制共享内存,可以通过参数对共享内存进行具体的操作。①函数原型。intshmctl(intshmid,intcmd,structshmid_ds*buf)②头文件。#include#include③参数。shmid:要控制的共享内存的id。cmd:决定执行何种控制操作,如IPC_RMID(删除)。buf:获取linux中描述共享内存的shmid_ds结构。基本不用。cmd可以去的参数如下,需要参考上面的结构体shmid_ds和ipc_perm:IPC_STAT:取本段的shmid_ds结构体存放在buf指向的结构体中。IPC_SET:根据buf指向的结构中的值,设置与该共享存储段相关的shmid_ds结构中的如下3个字段:shmperm.uid、shmperm.gid和shmperm.mode。该命令只能由两种进程执行:一种有效用户ID等于shm_perm.cuid或shmperm.uid;和一个具有超级用户权限的。IPC_RMID:从系统中删除共享内存段。直到使用该段的最后一个进程终止或与该段分离时,存储段才真正被删除。不管该段是否还在使用,段标识符都会被立即删除,因此不能再使用shmat连接到该段。该命令只能由两种进程执行:一种有效用户ID等于shm_perm.cuid或shm_perm.uid;和一个具有超级用户权限的。以下两条命令只能由超级用户执行:SHM_LOCK:将共享存储段锁定在内存中。SHM_UNLOCK:解锁共享内存段。④返回值。成功:根据操作返回不同的值。失败:-1.3下面的示例代码使用两个进程来演示共享内存的使用。示例代码如下,说明都在代码注释中。写内存.c。#include#include#include#include#include#include#include#defineSIZE1024//可以输入1K的字符串structSharedMemoryST{intReadWriteFlag;//CharCharData[SIZE]表示是谁放的;//字符数组保存用户输入的数据};intmain(intargc,char*argv[]){intshmid;intReadStatusFlag=1;//是否读取内存中的数据,1未读取structSharedMemoryST*shm;//共享内存结构变量charbuffer[SIZE];key_tkey=ftok("/tmp",12);//创建共享内存的键值。如果提示创建失败(一般是quit导致),可以修改读写进程的key值,改成相同的数字即可。//1创建共享内存shmid=shmget(key,sizeof(structSharedMemoryST),IPC_CREAT|IPC_EXCL|0777);if(shmid==-1)//如果创建失败{printf("\nCreatingsharedMemoryfail!\n\n");exit(1);}//2映射共享内存shm=shmat(shmid,NULL,0);//内存id,映射位置,映射标志(这个没有特殊要求)//3写的查询while(ReadStatusFlag)//循环检查写入共享内存的数据是否被读取,读取完毕后退出循环{while(shm->ReadWriteFlag==1){sleep(1);printf("\nWaitingreadmemory!\n");}//获取用户输入printf("\nPleaseinputdataorinput'quit'toexit!\n\n");fgets(buffer,SIZE,stdin);//参考Number:字符串的位置,长度,获取位置的方法//将用户输入的字符串放入共享内存strncpy(shm->CharData,buffer,SIZE);//参数:目的数据,来源data,datasizeshm->ReadWriteFlag=1;if(strncmp(buffer,"quit",4)==0)//最后一个参数为比较字符个数{ReadStatusFlag=0;//写入的数据共享内存已被读取}}//4脱离共享存储shmdt((constvoid*)shm);return0;}ReadMemory.c#include#include#include#include#include#include#defineSIZE1024//可以输入一个1K的字符串structSharedMemoryST{intReadWriteFlag;//表示读进程还是写进程放数据charCharData[SIZE];//保存用户输入的数据};intmain(intargc,char*argv[]){intshmid;intReadStatusFlag=1;//内存中数据是否被读取的标志,1表示没有被读取structSharedMemoryST*shm;//共享内存结构key_tkey=ftok("/tmp",12);//创建sharedmemoryKey值,如果提示创建失败,修改number即可,读写过程一定要改成相同的number//1create/getsharedmemoryshmid=shmget(key,sizeof(structSharedMemoryST),IPC_CREAT|0777);//allocationsize为结构体大小,1234为随机给定的key值//2映射共享内存shm=(structSharedMemoryST*)shmat(shmid,NULL,0);//内存id,映射位置,映射标志(这个没有特殊要求)shm->ReadWriteFlag=0;//3检查是否收到消息,退出while(ReadStatusFlag){//打印共享内存if(shm->ReadWriteFlag==1)//等于表示有对应数据{printf("\nThewritecontextis:%s\n",shm->CharData);shm->ReadWriteFlag=0;if(strncmp(shm->CharData,"quit",3)==0){读StatusFlag=0;//结束查询,退出}}}//4离开共享内存shmdt((constvoid*)shm);//5删除共享内存shmctl(shmid,IPC_RMID,0);}写共享内存先创建共享内存,写数据,读共享内存读取数据,通过flag查询方式,退出输入quit运行结果如下:本文转载自微信♂《埋伏的杂牌军》,可以通过以下二维码关注。转载本文请联系嵌入式杂军公众号。