IPC--共享内存

来源:互联网 发布:肯德基优惠券软件 编辑:程序博客网 时间:2024/05/29 15:26

有了之前的学习经验,共享内存对我们学习起来相对简单一些了,这里简单说说共享内存的一些,然后对于函数的分析直接在代码里面的注释部分有说明,如果还是不懂,可以先看看前面的关于IPC–信号量还有IPC–消息队列的讲解

共享内存以传递数据为目的,速度最快,不需要数据在内存还物理内存的来回的拷贝,直接访问访问虚拟地址空间

共享内存没有同步与互斥机制,这个时候我们可以结合着IPC–信号量进行进程间通信

下面我们直接粘贴代码

client.c

#include"comm.h"int main(){    int shmid = getShm(0);    int i = 0;    char* arr = (char*)shmat(shmid,NULL,0);    while(1)    {        sleep(1);        printf("%s\n",arr);        i++;        if(i==25)            break;    }    int dt =  shmdt(arr);    if(dt < 0)    {        perror("shmdt\n");        return -1;    }    return 0;}

comm.c

#include"comm.h"static int commShm(int size,int flag)   //size:共享内存的大小,flag:进行何种操作,是获取还是创建{    key_t key = ftok(PATHNAME,ID);    if(key < 0)    {        perror("key_t\n");        return -1;    }    int shmid = shmget(key,size,flag);  //key:键值,size:大小,这里传入的大小最好是4k(4096)的倍数                                    //因为4096是一页,如果我们传递的是4097,系统会自动的对齐到8192,                                    //但是因为我们申请的是4097,剩下的内存系统不会给你,flag:创建方式    if(shmid < 0)    {        perror("shmget\n");        return -2;    }    return shmid;}int creatShm(int size) //size:创建内存空间的大小{    return commShm(size,IPC_CREAT|IPC_EXCL|0666);}int getShm(int size){    return commShm(size,IPC_CREAT);   //size:默认设置为0}int desShm(int shmid){    int des = shmctl(shmid,IPC_RMID,NULL);    //shmid:删除的是哪一个共享内存,IPC_RMID:控制方式,这里是删除的意思                                            //NULL:这里是struct shmid_ds *buf,这是一个维护共享 内存的一个结构体                                            //暂时不关心    if(des < 0)    {        perror("shmctl\n");        return -1;    }    return des;}

comm.h

#ifndef _COMM_H_#define _COMM_H_#include<stdio.h>#include<sys/ipc.h>#include<sys/shm.h>#define PATHNAME "."#define ID 0x6666int creatShm(int size);int getShm(int size);int desShm(int shmid);#endif

server.c

#include"comm.h"int main(){    int i = 0;    int shmid = creatShm(27);    char* arr = (char*)shmat(shmid,NULL,0);   //这里可以把shmat当成是malloc使用,shmid:信号量标识符                                        //NULL:const void* shmaddr,虚拟地址空间,设置为NULL,这个是系统自己定义的                                        //返回值void* 这个时候我们要强制转换成我们需要的类型    for(;i<26;)    {        sleep(1);        arr[i] = 'A' + i;   //这里可以直接当成是malloc开辟的一个数组使用        i++;        arr[i] = 0;    }    int dt =  shmdt(arr);   //arr:这个就是我们上面的那个内存空间地址    if(dt < 0)    {        perror("shmdt\n");        return -1;    }    desShm(shmid);    return 0;}