【Linux】进程通信(共享内存Shared Memory)

本文详细介绍了Linux下共享内存的实现原理,包括共享内存的逻辑结构、相关函数的使用,如创建、连接、控制及分离。并探讨了在没有同步机制的情况下简单使用共享内存可能导致的问题,通过引入信号量解决进程同步问题,确保数据的一致性。
摘要由CSDN通过智能技术生成

(一)共享内存

(1)共享内存实现进程间通信的原理:
  • 共享内存在物理内存上开辟的空间
  • 多个进程可以将自己的虚拟空间地址映射到该块物理空间上
  • 多个进程都可以访问共享内存中的数据
  • 共享内存上的改动可以被其他进程看到
  • 并未实现同步机制,需要其他机制同步对共享内存的访问
(2)共享内存逻辑结构图

在这里插入图片描述

(二)共享内存相关函数

使用sys/shm.h

(1)创建(获得)共享内存

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

  • key_t :键值用于标识使用同一个共享内存段;(IPC_PRIVATE创建只属于进程的共享内存,但不是真正的私有)
  • size : 共享内存的容量(字节)
  • shmflg : IPC_CREAT(创建生效 / 获得忽略)(9个位的权限标志,与文件权限mode类似)
  • 返回值:成功返回共享内存标识符(非负数),失败-1
(2)共享内存和进程的连接(at)

void* shmat(int shm_id, const void* shm_addr, int shmflg);

  • shm_id : 共享内存标识符
  • shm_addr : 指定共享内存连接到当前进程的地址位置(通常是空指针NULL,表示让系统自己分配共享内存的地址
  • shmflg : 一般是0,SHM_RND(与shm_addr联合使用控制共享内存连接地址)、SHM_RDONLY(连接的内存只读)(一组位标志)
  • 返回值:成功返回指向共享内存第一个字节的指针,失败-1
    注意:
  • 共享内存的读写权限:由创建者、它的访问权限、当前进程属主决定(类似于文件权限)
  • 例外:shmflg & SHM_RDONLY为真时,此时的共享内存即使可写入,都不能写入;
(3)共享内存的控制(ctl)

int shmctl(int shm_id, int command, struct shmid_ds* buf);

  • shm_id : shmget的返回值,共享内存标识符
  • command : 采取的操作
命令 说明
IPC_STAT 把shmid_ds结构中的数据设置成共享内存的当前关联值
IPC_SET 若进程有足够的权限,就把共享内存的当前关联值设置成shmid_ds结构中给定的值
IPC_RMID 删除共享内存段
  • buff :是一个指针,指向包含共享内存模式和访问权限的结构
  • 返回值:成功返回0,失败-1

注意:删除一个正在处于连接状态的共享内存段后,通常还能够使用,直到最后一个进程脱离该共享内存段的连接(最好不要这样做!!哒咩)

(4)共享内存的分离(dt)

将共享内存从当前进程中分离;
int shmdt(const void* shm_addr);

  • shm_addr是shmat()返回的指针
  • 返回值:成功0,失败-1

注意:
共享内存分离,但未删除,只是分离的进程变得不可用

(三)练习巩固

(1)(未进程同步)简单的使用共享内存
  • a.c
#include <stdio.h>
#include <unistd.h>
#include <sys/shm.h>
#include <string.h>

//向共享内存中写入数据
void WriteToShm()
{
   
	//创建共享内存
	int shmid = shmget((key_t)8888, 128, IPC_CREAT | 0600);
	if(shmid == -1)
	{
   
		perror("shmget err");
		return;
	}
	//连接共享内存
	char* shm = shmat(shmid, NULL, 0);
	if(shm == NULL)
	{
   
		perror("shmat shm err");
		return;
	}
	//向共享内存中写入数据
	printf("input data : \n");
	while(1)
	{
   
		char buff[128] = {
   0};
		fgets(buff, 127, stdin);
		if(strncmp(buff, "end", 3) == 0)
		{
   
			break;			
		}
		strncpy(shm, buff, strlen(buff) - 1);
	}

	//脱离连接
	shmdt(shm);
}
int main()
{
   
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值