进程间通信方式1——共享内存

一、共享内存是什么?

共享内存允许两个或更多进程访问同一块内存,不同进程之间共享的内存通常为计算机中的同一段物理内存,就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针。当一个进程改变了这块地址中的内容的时候,其它进程都会察觉到这个更改。进程可以将同一段物理内存连接到他们自己的地址空间中(通过虚拟地址映射),所有的进程都可以访问共享内存中的地址。

共享内存的优缺点:
原文链接:https://blog.csdn.net/d_guco/article/details/53524854

1.共享内存号称是最快的进程间通信方式。
2.共享内存适用于大数据量的传输,读取不等待写入,需要设置同步,可以用信号量来实现对共享内存同步访问控制。可以通过管道发送同步信号。管道适合传输小数据量。
3.通过名字知道它是基于内存的,所以他只能在同一主机上使用,如果我们要做分布式应用或者跨物理机通信,那么socket就是我们唯一的选择了。

二、书写代码时的可能出现的错误

  • 向共享内存中存放数据时,需在共享内存映射之后再存放数据,否则存放不成功

  • 存放数据时若出现段错误时,则可能是因为代码中出现了野指针

  • 若两个进程中开辟的共享内存空间不一致则报错:shmget: Invalid argument

三、代码例程

参考知乎了知乎上的代码例程

情景:创建两个进程,在 A 进程中创建一个共享内存,并向其写入数据(结构体形式进行数据传输 ),通过 B 进程从共享内存中读取数据

A写进程:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define BUFSZ 100
struct Mem{
    int type ;
    char data[BUFSZ];

};
int main(int argc, char *argv[])
{
    //struct Mem mem1;
    int shmid;
    int ret;
    key_t key;
    struct Mem *shmadd;
    
    //创建key值
    key = ftok("/dev/ppp", 2021);
    if(key == -1)
    {
        perror("ftok");
    }
 
    //创建共享内存
    shmid = shmget(key, BUFSZ*sizeof(char)+sizeof(int), IPC_CREAT|0666);    
    if(shmid < 0)
    {
        perror("shmget");
        exit(-1);
    }

  	
    //映射
    shmadd = (struct Mem *)shmat(shmid, NULL, 0);
    if(shmadd < 0)
    {
        perror("shmat");
        _exit(-1);
    }
	
    // 共享内存清空
    memset(shmadd, 0, sizeof(shmadd));	
    //拷贝数据至共享内存区
    printf("copy data to shared-memory\n");   
    //bzero(mem1.data, BUFSZ); // 共享内存清空
    (*shmadd).type = 1;
    strcpy((*shmadd).data, "how are you, lh\n");
 
    //拷贝数据至共享内存区
    //printf("copy data to shared-memory\n");
    //strcpy(shmadd, "how are you, lh\n");
    printf("type = [%d]\n", (*shmadd).type);
    printf("data = [%s]\n", (*shmadd).data);  
    return 0;
}

B读进程:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define BUFSZ 100
typedef struct MemA{
    int type;
    char data[BUFSZ];
}MemA;
int main(int argc, char *argv[])
{
    int shmid;
    int ret;
    key_t key;
    MemA *shmadd;
 
    //创建key值
    key = ftok("/dev/ppp", 2021);
    if(key == -1)
    {
        perror("ftok");
    }
 
    system("ipcs -m"); //查看共享内存
 
    //打开共享内存
    shmid = shmget(key, BUFSZ  +4, IPC_CREAT|0666);
    if(shmid < 0)
    {
	printf("error");
        perror("shmget");
        exit(-1);
    }
 
    //映射
    shmadd = (MemA *)shmat(shmid, NULL, 0);
    if(shmadd < 0)
    {
        perror("shmat");
        exit(-1);
    }
 
    //读共享内存区数据
    printf("type = [%d]\n", (*shmadd).type);
    printf("data = [%s]\n", (*shmadd).data);
 
    //分离共享内存和当前进程
    ret = shmdt(shmadd);
    if(ret < 0)
    {
        perror("shmdt");
        exit(1);
    }
    else
    {
        printf("deleted shared-memory\n");
    }
 
    //删除共享内存
    shmctl(shmid, IPC_RMID, NULL);
 
    system("ipcs -m"); //查看共享内存
 
    return 0;
}

提示:
代码中所用到的函数详情可参考链接: https://cloud.tencent.com/developer/article/1527533.


总结

1.实现数据以结构体形式进行进程之间通信。
2.代码未提供同步机制

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值