Linux进程通讯之共享内存的使用(指针操作方式)

本文详细介绍了如何在C语言中使用shmat和shmdt函数实现进程间共享内存的挂载、数据操作和分离。通过示例展示了创建共享内存、附着进程、修改数据和读取数据的过程,以及相关系统调用和关键函数的使用方法。
摘要由CSDN通过智能技术生成

函数说明

1、将共享内存挂载至进程:

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

参数shmid是要附加的共享内存区标示符。
总是把参数shmaddr设为0。
参数shmflg可以为SHM_RDONLY,这意味着附加段是只读的。
shmat成功返回被附加了段的地址,失败返回-1,并设置errno。

2、将附在共享内存上的进程分离:

int shmdt(const void *shmaddr);

参数必须是挂在函数返回的指针。这个地址必须是shmat返回的。

图解说明:
在这里插入图片描述

程序:

实现一个进程修改共享内存中的数据,另一个进程读取共享内存中的数据。

步骤:

1、创建并编写makefile文件:

.SUFFIXES:.c .o
 
CC=gcc
 
SRCS1=main1.c
OBJS1=$(SRCS1:.c=.o)
EXEC1=main1
 
SRCS2=main2.c
OBJS2=$(SRCS2:.c=.o)
EXEC2=main2
 
start: $(OBJS1) $(OBJS2)
	$(CC) -o $(EXEC1) $(OBJS1)
	$(CC) -o $(EXEC2) $(OBJS2)
	@echo "--------------------------OK------------------------"
 
.c.o:
	$(CC) -Wall -o $@ -c $<
 
clean:
	rm -rf $(OBJS1) $(EXEC1)
	rm -rf $(OBJS2) $(EXEC2)

2、查看显示共享内存段信息(使用共享内存,需提前创建好共享内存,创建流程看下面附注)。

[negivup@negivup mycode]$ ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x00000000 229381     negivup    666        1024       0    

3、创建并编写源文件main1.c:

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/shm.h>
 
int main(int argc, char *args[])
{
	// 将进程依附到共享内存上
	// 第一个参数是共享内存的shmid,第二个参数和第三个参数都是0
	// 函数的返回值是一个指向共享内存的地址,指针类型是void*
	void *p_temp = shmat(229381, 0, 0);
	// 转换指针的类型根据要写入共享内存的数据类型而定
	char *p = (char*)p_temp;
	// 将字符串拷贝至共享区
	strcpy(p, "hello\n");
	// 将进程从共享内存上剥离,传递的参数是shmat返回的地址
	shmdt(p);
	return 0;
}

4、创建并编写源文件main2.c:

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/shm.h>
 
int main(int argc, char *args[])
{
	// 将进程依附到共享内存上
	// 第一个参数是共享内存的shmid,第二个参数和第三个参数都是0
	// 函数的返回值是一个指向共享内存的地址,指针类型是void*
	void *p_temp = shmat(229381, 0, 0);
	// 转换指针的类型根据要读取的共享内存的数据类型而定
	char *p = (char*)p_temp;
	// 将读取的内容显示到屏幕
	printf("%s", p);
	// 将进程从共享内存上剥离,传递的参数是shmat返回的地址
	shmdt(p);
	return 0;
}

5、编译并执行程序:

[negivup@negivup mycode]$ make
gcc -Wall -o main1.o -c main1.c
gcc -Wall -o main2.o -c main2.c
gcc -o main1 main1.o
gcc -o main2 main2.o
--------------------------OK------------------------
[negivup@negivup mycode]$ main1                        main1是向共享内存中写入数据
[negivup@negivup mycode]$ main2                        main2是从共享内存中读取数据
hello

附注

  1. 函数说明—创建共享内存使用的函数:
int shmget(key_t key, size_t size, int shm-flg);
2、参数key既可以是IPC_PRIVATE(0),也可是是ftok函数返回的一个关键字。
3、参数size指定段的大小。
4、参数flags
八进制数,0xxx。转化为二进制后分别代表rw-rw-rw-
IPC_CREAT:当shmflg&IPC_CREAT为真时,如果内核中不存在键值与key相等的共享内存,则新建一个共享内存;如果存在这样的共享内存,返回此共享内存的标识符;IPC_CREAT|IPC_EXCL:如果内核中不存在键值 与key相等的共享内存,则新建一个共享内存;如果存在这样的共享内存则报错
5、shmget成功返回shmid,失败返回-1。
6、在命令行执行ipcs –m 显示,已经成功的创建了一块共享内存区。
  1. 创建共享内存
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
 
int main(int argc, char *args[])
{
	// 建立一块共享内存区域
	int shid = shmget(IPC_PRIVATE, 1024, IPC_CREAT | 0666);
	// 输出共享内存的id号
	printf("shid = %d\n", shid);
	return 0;
}
  1. 创建makefile
.SUFFIXES:.c .o

CC=gcc

SRCS=main.c
OBJS=$(SRCS:.c=.o)
EXEC=main

start: $(OBJS)
	$(CC) -o $(EXEC) $(OBJS)
	@echo "--------------------------OK------------------------"

.c.o:
	$(CC) -Wall -o $@ -c $<

clean:
	rm -rf $(OBJS) $(EXEC)
  1. 编译并查看共享内存
[negivup@negivup mycode]$ make
gcc -Wall -o main.o -c main.c
gcc -o main main.o
--------------------------OK------------------------
[negivup@negivup mycode]$ main
shid = 229381
[negivup@negivup mycode]$ ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x00000000 229381     negivup    666        1024       0   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值