进程通信2-共享内存

共享内存,就是允许两个不相关的进程访问同一个逻辑内存,然后进行通信

1.数据的共享进程间的数据直接访问内存,是最快的进程通信方式,但并未提供同步机制,通常需要用其他的机制来同步,例如信号量
2.共享内存代码申请的适合,尽量是一页大小4k的倍数申请,否则容易产生内存碎片

这里用一张图来说明:
两个不同的虚拟地址通过页表映射到物理空间的同一区域,它们所指向的这块区域即共享内存。在这里插入图片描述
代码实现:
int shmget(key_t key, size_t size, int shmflg);//创建共享内存
void *shmat(int shmid, const void *shmaddr, int shmflg);//挂载共享内存
int shmdt(const void *shmaddr);//删除与共享内存的关联
int shmctl(int shmid, int cmd, struct shmid_ds *buf);//销毁共享内存
1.func.h

#pragma once

#include <stdio.h>
#include <error.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include<unistd.h>
constexpr auto PATHNAME = ".";
constexpr auto PROJ_ID = 066;
int CreatShmid(int size);
int GetShmid(int size);
int Destory(int shmid);
int commShmid(int size, int flag)//创建
{
    
    
	key_t key = ftok(PATHNAME, PROJ_ID);
	if (key > 0)
	{
    
    
		return shmget(key, size, flag);
	}
	else
	{
    
    
		perror("ftok");
		return -1;
	}
}

int CreatShmid(int size)//创建
{
    
    
	return commShmid(size, IPC_CREAT | IPC_EXCL | 0666);
}
int GetShmid(int size)//获取shmid
{
    
    
	return commShmid(size, IPC_CREAT);
}
int Destory(int shmid)//销毁
{
    
    
	return shmctl(shmid, 0, IPC_RMID);
}

2.进程A.cpp

#include "func.h"
int main()
{
    
    
    int shmid=CreatShmid(4097);
    if(shmid>0)
    {
    
       
        int i=0;
        char *addr=shmat(shmid,NULL,0);
        while(i<20)
        {
    
       
            addr[i++]='A';
            addr[i]='\0';
            sleep(1);
        }   
        if(shmdt(addr)==-1)
        {
    
       
            perror("shmat");
            return -3; 
        }   
 
    }   
   else
    {
    
       
        perror("CreatShmid");
        return -1;
    }
    if(Destory(shmid)<0)
    {
    
    
        perror("Destory");
        return -2;
    }
    return 0;
}

3.进程B.cpp

#include "comm.h"
int main()
{
    int shmid=GetShmid(4097);
    if(shmid>0)
    {   
        int i=0;
        char *addr=shmat(shmid,NULL,0);
        while(i<20)
        {   
            printf("%s\n",addr);
            sleep(1);
            i++;
        }   
        if(shmdt(addr)==-1)
        {   
            perror("shmdt");
            return-1;
        }   
    }   
    else
    {   
        perror("GetShmid");
      return -2;
    }
    return 0;
}

运行结果
在这里插入图片描述

おすすめ

転載: blog.csdn.net/qq_40861091/article/details/102183142