进程间通信之共享内存

        为了多个进程能够 交换信息 ,在内核中留出一段内存区,可以由需要访问的多个进程把内存区的地址映 射到自己的进程中,可以操作这段空间,可以进行通信。 进程就可以直接读写这段空间,避免拷贝,提高效率。
共享内存的使用步骤:
        1. 创建 / 打开共享内存
·       2. 映射共享内存,把共享内存的空间映射到进程中(以地址提供地址)
        3. 进行操作
        4. 撤销共享内存映射
        5. 删除共享内存对象
使用共享内存需要用到的函数
1、 创建 / 打开共享内存
#include <sys/ipc.h> 
#include <sys/shm.h> 

//创建 、 打开一个共享内存 

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

参数:
    参数1:key_t key//:要创建/打开的共享内存的编号
    参数2:size_t size//:要创建的共享内存的空间大小,以字节为单位 
    参数3:int shmflg//:选项 IPC_CREAT:要创建 权限:读写执行 

返回值:int 
    成功:返回打开/创建的共享内存的标识id,打开的共享内存是谁 
    失败:-1,设置错误码

   2、 映射共享内存,把共享内存的空间映射到进程中(以地址提供地址)

#include <sys/types.h> 
#include <sys/ipc.h> 

//计算key值 
key_t ftok(const char *pathname, int proj_id); 

参数:
    参数1:const char *pathname:文件路径 
    参数2:int proj_id:
#include <sys/types.h>
#include <sys/shm.h>
//映射共享内存到进程中
void * shmat(int shmid, const void *shmaddr, int shmflg);
参数:
	参数1:int shmid:打开的共享内存,映射哪个共享内存
	参数2:const void *shmaddr:共享内存映射到进程中,具体映射到进程的哪个的地址
			NULL:系统自动选择地址完成映射
	参数3:int shmflg:选项
			SHM_RDONLY:共享内存只读
			0:读写
返回值:
	void *:指针,地址
	成功:返回映射到进程的地址
	失败:返回(void *)-1

.3、撤销共享内存映射

//撤销共享内存的映射
int shmdt(const void *shmaddr);
参数:
	参数1:
		const void *shmaddr://刚才映射的地址,要进行撤销
返回值:
	成功:返回0
	失败:返回-1,设置错误码

4、共享内存控制

#include <sys/ipc.h>
#include <sys/shm.h>

//共享内存控制
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数:
	参数1:
        int shmit:打开的共享内存,映射哪个共享内存
	参数2:
		int cmd:控制命令
			IPC_STAT:获取共享内存信息,把共享内存的信息,存储在第三个参数表示的地址中
			IPC_SET:设置共享内存信息,把共享内存的信息存储到结构体中,作为第三个参数地址,设置到内核
			IPC_RMID:关闭共享内存,删除,第三个参数为NULL
	参数3:
		struct shmid_ds *buf://结构体地址,设置、获取都是使用这个地址,表示存储到内核,存储到程序
返回值:
	失败:返回-1
	成功:IPC_RMID返回0

使用案例:

写的程序

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


int main()
{
	
	key_t key = ftok("/home/ubuntu",10);//计算出key值,应该和创建的进程使用的key一致

	int shmid = shmget(key,1024,0666 | IPC_CREAT);//创建 打开共享内存,得到标识

	if(shmid < 0)
	{
		perror("shm get error");
		return -1;
	}

	char * p = shmat(shmid,NULL,0);    //映射共享内存的地址

	while(1)
	{
		if(strcmp(p,"quit\n") == 0)    //quit退出
		{
			break;
		}
		printf("%s",p);
		sleep(1);
	}
	
	shmdt(p);        //撤销共享内存

	shmctl(shmid,IPC_RMID,NULL);    //删除共享内存
	
	return 0;
}

读的程序

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

int main()
{
	
	key_t key = ftok("/home/ubuntu",10);//计算出key值

	int shmid = shmget(key,1024,0666 | IPC_CREAT);//创建 打开共享内存,得到标识

	if(shmid < 0)
	{
		perror("shm get error");
		return -1;
	}

	char * p = shmat(shmid,NULL,0);

	while(1)           //唯一不同的地方
	{
		fgets(p,1024,stdin);
		if(strcmp(p,"quit\n")==0)
		{
			break;
		}
	}

	shmdt(p);

	shmctl(shmid,IPC_RMID,NULL);
	
	return 0;
}

其实这种通信的话,在进行通信的时候,一但共享内存的值发生改变,那么其内存空间的值也就发生改变了。一变则全部都变了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啵啵520520

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值