进程间通信——共享内存

共享内存

创新互联-专业网站定制、快速模板网站建设、高性价比木垒哈萨克网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式木垒哈萨克网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖木垒哈萨克地区。费用合理售后完善,10年实体公司更值得信赖。


进程间通信的本质是让不同的进程访问一块公共的资源。

1、共享内存是进程间通信最快的方式(为什么)

2、共享内存不提供任何的同步与互斥关系。(由用户维护,可以用信号量)

以下图解释了问题1,原因是,由于共享内存的机制,两个进程不需要拷贝拷贝数据,这个特点可能在数据较少的情况下看不出来,但是数据较多时,优势较为明显。

下图是shmat之前之后的共享内存示意图:(shmget获得共享内存后需要挂接)

进程间通信——共享内存

进程间通信——共享内存

函数:

用于Linux进程通信共享内存。共享内存函数由shmget、shmat、shmdt、shmctl四个函数组成。

shmat(把共享内存区对象映射到调用进程的地址空间)

void *shmat(int shmid, const void *shmaddr, int shmflg)

参数:

shmid共享内存标识符
shmaddr指定共享内存出现在进程内存地址的什么位置,直接指定为NULL让内核自己决定一个合适的地址位置
shmflg如果设置为SHM_RDONLY是只读模式,其他为读写模式

返回值:成功返回附加好的共享内存地址

shmdt(断开共享内存连接)

int shmdt(const void *shmaddr)

参数:

shmaddr:连接的共享内存的起始地址

返回值:成功返回0

shmget(得到一个共享内存标识符或创建一个共享内存对象)

int shmget(key_t key, size_t size, int shmflg)

参数:

key大于0的32位整数:视参数shmflg来确定操作。通常要求此值来源于ftok返回的IPC键值
size大于0的整数:新建的共享内存大小,以字节为单位
flags有IPC_CREAT和IPC_EXCL(用法同前面写的一致)

返回值:成功返回共享内存标示符

注:system V分配内存的方法以页为基本单位,一般以页的整数倍分配。

shmctl完成对共享内存的控制

int shmctl(int shmid, int cmd, struct shmid_ds *buf)

参数:


shmid

共享内存标识符

cmdIPC_STAT:得到共享内存的状态,把共享内存的shmid_ds结构复制到buf中
IPC_SET:改变共享内存的状态,把buf所指的shmid_ds结构中的uid、gid、mode复制到共享内存的shmid_ds结构内
IPC_RMID:删除这片共享内存
buf
共享内存管理结构体。具体说明参见共享内存内核结构定义部分

共享内存实现通信的例子

comm.h

#pragma once
#include
#include
#include
#include
#define _PATH_NAME_ "/temp"
#define _PROJ_ID_ 0x6666

int create_shm(int size);
int get_shm();
int destory_shm(int shm_id);
void* shm_at(int shm_id);
int shm_dt(void*shmaddr);

comm.c

#include"comm.h"

static int comm_create_shm(int size,int flags)
{
    key_t _key = ftok(_PATH_NAME_,_PROJ_ID_);
    if(_key<0)
    {
        perror("ftok");
        return -1;
    }
//    int shm_id=shmget(_key,size,IPC_CREAT | IPC_EXCL);

    int shm_id=shmget(_key,size,flags);
    if(shm_id < 0)
    {
        perror("shmget");
        return -2;
    }
    return shm_id;
}

int create_shm(int size)
{
    int flags = IPC_CREAT | IPC_EXCL|0666;
    return  comm_create_shm(size,flags);
}
int get_shm()
{
    
    int flags = IPC_CREAT;
    return  comm_create_shm(0,flags);
}
int destory_shm(int shm_id)
{
    if(shmctl(shm_id,IPC_RMID,NULL)<0)
    {    
        perror("shmctl");
        return -1;
    }
    return 0;
}

void* shm_at(int shm_id)
{
    return shmat(shm_id,NULL,0);
}
int shm_dt(void* shmaddr)
{
    return shmdt(shmaddr);
}

server.c

#include"comm.c"

int main()
{
    int shm_id = create_shm(4096);
    sleep(5);
    char* buf = (char*)shm_at(shm_id);
    sleep(1);
    sleep(1);
    while(1)
    {
        printf("%s\n",buf);
        sleep(1);
        if(strcmp(buf,"AAAAA") == 0)
        {
            break;
        }
    }
    shm_dt(buf);
    sleep(5);
    destory_sem(sem_id);
    return 0;
}

client.c

#include"comm.c"

int main()
{
    int shm_id = get_shm();
    char* buf = (char*)shm_at(shm_id);
    int index = 0;
    while(1)
    {
        buf[index++]='A';
        buf[index]='\0';
        sleep(1);
        if(index>5)
        {
            break;
        }
    }
    sleep(5);
    shm_dt(buf);
    sleep(5);
    return 0;
}


当前题目:进程间通信——共享内存
本文链接:http://scyanting.com/article/pjohsg.html