进程间通信——共享内存

【共享内存概述】

       共享内存时一种最为高效的进程间通信方式,进程可以直接读写内存,不需要任何数据的复制。为了在多个进程之间交换信息,内核专门留出了一块内存区,这段内存区可以由需要访问的进程将其映射到自己的私有地址空间。因此,进程就可以直接读写这一内存区而不需要进行数据复制,从而大大提高了效率。但共享内存本身并不具备同步机制,所以当多个进程共享一段内存时,就需要借助互斥锁、信号量等实现同步。


 

 

【共享内存编程】

 

【编程步骤】

       一、创建共享内存,用到的函数是shmget(),也就是从内存中获得一段共享内存区域;

       二、映射共享内存,也就是把这段创建的共享内存映射到具体的进程空间中,使用到的函数是shmat()。至此就可以使用这段共享内存了,即使用不带缓冲的I/O读写命令对其进行操作。

       三、撤销映射,其函数为shmdt()。

 

【函数说明】

1、shmget()函数

头文件:

        #include <sys/types.h>

        #include <sys/ipc.h>

        #include <sys/shm.h>

 

函数原型:

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

 

传入值:

        key:共享内存的键值,多个进程可以通过它访问同一个共享内存,其中有个特殊值IPC_PRIVATE。它用于创建当前进程的私有共享内存。

        size:共享内存区大小

        shmflg:同open()函数权限位,也可以用八进制表示法

 

返回值:

        成功返回共享内存段标识符

        失败返回-1

 

2、shmat()函数

头文件:

        #include <sys/types.h>

        #include <sys/ipc.h>

        #include <sys/shm.h>

 

函数原型:

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

 

传入值:

        shmid:要映射的共享内存区标识符

        shmaddr:将共享内存映射到指定地址(若为0则表示系统自动分配地址并把该段共享内存映射到调用进程的地址空间)

        shmflg:默认0,共享内存可读写

                      SHM_RDONLY,共享内存只读

 

返回值:

        成功返回被映射的地址段

        失败返回-1

 

3、shmdt()函数

头文件:

        #include <sys/types.h>

        #include <sys/ipc.h>

        #include <sys/shm.h>

 

函数原型:

        int shmdt(const void *shmaddr)

 

传入值:

        shmaddr:被映射的共享内存段地址

 

返回值:

        成功返回0

        失败返回-1

 

 

【代码示例】

 

【头文件】

#ifndef __SHM_H__
#define __SHM_H__

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

typedef struct st_shm
{
	sem_t sem1;
	sem_t sem2;
	int data;
}sh;

#endif


 

【程序1:生产】

/*******
*共享内存
*******/
#include "shm.h"

int main()
{
	int shmid = -1;
	sh *pshm = NULL;
	int ret;

	//创建共享内存
	shmid = shmget((key_t)0x01020304, sizeof(sh), IPC_CREAT|0666);
	if (shmid < 0)
	{
		perror("shmget");
		exit(1);
	}

	//加载共享内存
	pshm = (sh *)shmat(shmid, NULL, 0);
	if (pshm == (void *)-1)
	{
		perror("shmat");
		exit(1);
	}

	//信号量初始化
	ret = sem_init(&(pshm->sem1), 1, 1);
	if (ret < 0)
	{
		perror("sem_init");
		exit(1);
	}
	ret = sem_init(&(pshm->sem2), 1, 0);
	if (ret < 0)
	{
		perror("sem_init");
		exit(1);
	}

	pshm->data = 0;

	while (1)
	{
		sem_wait(&pshm->sem1);

		pshm->data++;
		printf("生产【%d】\n", pshm->data);
		sleep(1);

		sem_post(&pshm->sem2);
	}
}


 

【程序2:消费】

/*******
*共享内存
*******/
#include "shm.h"

int main()
{
	int shmid = -1;
	sh *pshm = NULL;
	int ret;

	//获得共享内存
	shmid = shmget((key_t)0x01020304, sizeof(sh), 0);
	if (shmid < 0)
	{
		perror("shmget");
		exit(1);
	}

	//映射共享内存
	pshm = (sh *)shmat(shmid, NULL, 0);
	if (pshm == (void *)-1)
	{
		perror("shmat");
		exit(1);
	}

	while (1)
	{
		sem_wait(&pshm->sem2);

		printf("消费【%d】\n", pshm->data);

		sem_post(&pshm->sem1);
	}
}



 


 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Linux下,进程间通信的一种方式是通过共享内存来实现的。共享内存允许两个或多个进程共享一定的存储区,这样它们就可以直接访问同一块内存区域,而不需要进行数据的复制。共享内存是一种高效的进程间通信方式,因为数据直接写入内存,不需要多次数据拷贝,所以传输速度很快\[2\]。 在使用共享内存进行进程间通信时,需要给共享内存创建一个唯一的身份ID,以便区分不同的共享内存。当进程需要访问共享内存时,需要在映射时带上这个ID,这样就可以确定访问的是哪一个共享内存\[3\]。 需要注意的是,共享内存并没有提供同步机制,也就是说,在一个进程结束对共享内存的写操作之前,并没有自动机制可以阻止另一个进程开始对它进行读取。为了实现多个进程对共享内存的同步访问,通常会使用信号量来实现对共享内存的同步访问控制\[2\]。 总结起来,Linux下的共享内存是一种高效的进程间通信方式,允许多个进程共享一块存储区。通过给共享内存创建唯一的身份ID,可以区分不同的共享内存。然而,共享内存并没有提供同步机制,需要使用信号量来实现对共享内存的同步访问控制\[2\]\[3\]。 #### 引用[.reference_title] - *1* *3* [Linux多进程间通信——共享内存实现](https://blog.csdn.net/zhm1949/article/details/124909541)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Linux下进程间通信方式——共享内存](https://blog.csdn.net/xujianjun229/article/details/118584955)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值