linux下最快的进程间通信方式共享

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_40921797/article/details/82774903

什么是共享内存

共享内存 是多个进程都可以共享访问的一段内存区域。通过指针指向这个内存区域,一旦有一个进程把该指针所指向内容修改,其他同指向的进程也会感知到这个改变。

问什么说共享内存是最快的进程间通信方式

因为共享内存是直接将一块内存区域映射到虚拟地址空间中,因此在数据通信传输的过程中,相比较其他的通信方式少了将数据从用户态到内核态的数据拷贝过程。
什么意思,就是说这种通信方式,已经把数据拿到了地址空间,再取数据不需要再涉及到内核,不涉及执行进入内核的系统调用 来传递数据。
在这里插入图片描述

共享内存使用步骤

1.创建共享内存

#include<sys/ipc.h>
#include<sys/shm.h>
int shmget(key_t key,size_t size,int shmflg);
//参数:key是共享内存段名字,进程间通信的标识符,和我们消息队列定义的一样。需要自己define 定义
//size 是共享内存的大小
//shmflg是创建权限,共九种,类似于创建文件时的mode权限
//返回值:成功返回一个非负整数是操作句柄,失败返回-1

2.将共享内存映射到虚拟地址空间

#include<sys/types.h>
#include<sys/shm.h>
void * shmat (int shmid, const void * shmaddr, int shmflg);
//参数:shmid 是shmget返回的操作句柄,
//shmaddr 是映射第起始地址,如果参数给NULL则系统分配
//shmflg 是权限只读、只写、读写等,系统给出类一些宏定义,比如SHM_PDONLY 表示只读,无标志标识读写
SHM_RND表示地址向下调职SHMLBA的整数倍
//返回值,映射的虚拟地址的首地址

3.操作内存数据进行通信
4.解除映射、删除共享内存

#include<sys/types.h>
#include<sys/shm.h>
int shmdt (const void * shmaddr);//解除映射
//参数:共享内存的映射首地址 
//返回值:成功0,失败-1
#include<sys/ipc.h>
#include<sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds * buf);//删除共享内存
//参数:shmid 是句柄,依然是shmget返回的那个
//cmd 是要执行的操作,系统给出了一些宏定义,和权限类似。IPC_RMID代表删除
//buf 用于接收共享内存描述信息大小,时间信息等,若用于不关心则传NULL过去。
//返回值 成功返回0 ,失败返回-1

特别注意:当共享内存依然还和其他内存保有映射关系的时候,shmctl并不会直接删除共享内存,而是等待全部进程和该共享内存解除映射后才会删除,但是这段时间会拒绝新的映射建立

关于共享内存的 操作例子

//shm_write.c //用于向共享内存写入数据
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#define IPC_KEY 0x12312345
int main()
{
	int shmid = -1;
	shmid = shmget(IPC_KEY,32,IPC_CREAT | 0664);
	if(shmid < 0)
	{
		perror("shmget error");
		return -1;
	}
	void * shm_start = shmat(shmid,NULL,0);
	if(shm_start == (void *) -1)
	{
		perror("shmat error");
		return -1;
	}
	while(1)
	{
		printf("please input :");
		fflush(stdout);//清理输入缓冲区
		memset(shm_start,0,32);//把从start开始的32个字节的空间清理初始化为0
		scanf("%s",(void *)shm_start);
		sleep(1);
	}
	shmdt(shm_start);
	shmctl(shmid,IPC_RMID,NULL);
	return 0;
}
// shm_read.c用于从共享内存中读取数据
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#define IPC_KEY 0x12312345
int main()
{
	int shmid = -1;//接收句柄
	shmid = shmget(IPC_KEY,32,IPC_CREAT | 0664);
	if(shmid < 0)
	{
		perror("shmget errnr");
		return -1;
	}
	void * shm_start = shmat(shmid,NULL,0 );
	if(shm_start == (void *) -1)
	{
		perror("shmat error");
		return -1;
	}
	while(1)
	{
		printf("%s\n",(char *)shm_start);printf("%s\n",(char *)shm_start);
		sleep(1);
	}
	shmdt(shm_start);
	shmctl(shmid,IPC_RMID,NULL);
	return 0;
}

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

展开阅读全文

没有更多推荐了,返回首页