当前位置:网站首页>多进程编程(四):共享内存
多进程编程(四):共享内存
2022-07-02 23:05:00 【HDD615】
定义:
共享内存(Shared Memory)就是允许两个或多个进程访问同一个内存空间,是在多进程通信的最高效的方式。
操作系统将不同进程之间共享内存安排为同一段物理内存,进程可以将共享内存连接到它们自己的地址空间中,如果某个进程修改了共享内存中的数据,其它的进程读到的数据也将会改变。由于共享内存会成为进程用户空间的一部分,所有这种通信方式不需要内核介入。
共享内存并未提供锁机制,也就是说,在某一个进程对共享内存的进行读写的时候,不会阻止其它的进程对它的读写,可能会出现数据的错乱。
函数:
1、必备头文件
#include <sys/ipc.h>
#include <sys/shm.h>
2、shmget()
获取或创建共享内存
// 获取或者创建共享内存
int shmget(key_t key, size_t size, int shmflg);
- key是共享内存的键值,是一个整数,是共享内存在系统中的编号,不同共享内存的编号不同。一般使用十六进制。
- size表示待创建共享内存的大小,以字节为单位
- shmflg表示共享内存的访问权限,与文件的权限一样,
0666 | IPC_CREAT 表示全部用户对它可读写
- 返回值:返回共享内存标识
3、shmat()
把共享内存连接到当前进程的地址空间
void *shmat(int shm_id, const void *shm_addr, int shmflg);
- shm_id表示由 shmget函数返回的 共享内存的标识号
- shm_addr指定共享内存连接到当前进程中的地址位置,通常为 NULL,表示让系统来选择共享内存的地址。
- shm_flg是一组标志位,通常为0
- 返回值:
调用成功:返回一个指向共享内存第一个字节的指针
调用失败:返回 -1
4、shmdt()
将共享内存从当前进程中分离,相当于 shmat()
函数的反操作
int shmdt(const void *shmaddr);
- shmaddr是 shmat函数 返回的地址
- 返回值:
调用成功:返回 0
调用失败:返回 -1
5、shmctl()
删除共享内存
int shmctl(int shm_id, int command, struct shmid_ds *buf);
- shm_id是共享内存的标识号
- command 填写 IPC_RMID
- buf 填写 0
- 返回值:
调用成功:返回 0
调用失败:返回 -1
使用步骤
- 调用
shmget()
函数创建一个新共享内存段或取得一个现有的共享内存段的标识号。返回后续可调用的需要用到的共享内存标识符。 - 在进程中使用
shmat()
函数附上共享内存段,即让该共享内存段成为调用进程的虚拟内存中的一部分(进程绑定共享内存段) - 使用
shmat()
返回的内存地址指针,就可以在程序中对该共享内存段进行操作(写操作/读操作)。 - 调用
shmdt()
函数,让进程和共享内存段分离,进程无法再操作共享内存了。(只是分离,共享内存依然存在) - 调用
shmctl()
函数,删除共享内存段,只有当与该共享内存段绑定好的进程都分离后,才会销毁,只有一个进程需要执行这一步。
举例
// write_shm.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main()
{
int shmid; // 共享内存标识符
// 创建共享内存,键值为0x5005,共1024字节。
if ( (shmid = shmget((key_t)0x5005, 1024, 0666 | IPC_CREAT)) == -1)
{
printf("shmat(0x5005) failed\n");
return -1;
}
char *ptext = NULL; // 用于指向共享内存的指针
// 将共享内存连接到当前进程的地址空间,由ptext指针指向它
ptext = (char *)shmat(shmid, NULL, 0);
// 操作本程序的ptext指针,就是操作共享内存
char *str = "Hello world!";
memcpy(ptext, str, strlen(str));
// 把共享内存从当前进程中分离
shmdt(ptext);
return 0;
}
// read_shm.c
int main()
{
int shmid; // 共享内存标识符
// 创建共享内存,键值为0x5005,共1024字节。
if ( (shmid = shmget((key_t)0x5005, 1024, 0666 | IPC_CREAT)) == -1)
{
printf("shmat(0x5005) failed\n");
return -1;
}
char *ptext = NULL; // 用于指向共享内存的指针
// 将共享内存连接到当前进程的地址空间,由ptext指针指向它
ptext = (char *)shmat(shmid, NULL, 0);
// 操作本程序的ptext指针,就是操作共享内存
printf("%s\n", ptext);
// 把共享内存从当前进程中分离
shmdt(ptext);
// 删除共享内存
if (shmctl(shmid, IPC_RMID, 0) == -1)
{
printf("shmctl(0x5005) failed\n");
return -1;
}
}
read_shm.c
的输出结果:
Hello world!
可以看出,write_shm.c
申请共享内存,并写入数据,read_shm
获取共享内存标识号,并绑定进程,读取该共享内存中的数据。
查看共享内存
ipcs -m # 查看现有的所有共享内存段
ipcrm -m shmid # 根据共享内存段的标识号,删除共享内存
边栏推荐
- RTP 接发ps流工具改进(二)
- zhvoice
- Chapter 4 of getting started with MySQL: data types stored in data tables
- Returns the maximum distance between two nodes of a binary tree
- Bypass AV with golang
- 顶级 DevOps 工具链大盘点
- How do educators find foreign language references?
- 【单片机项目实训】八路抢答器
- 1380. Lucky numbers in the matrix
- [reading notes] phased summary of writing reading notes
猜你喜欢
How much do you know about synchronized?
Digital twin smart factory develops digital twin factory solutions
Confluence的PDF导出中文文档异常显示问题解决
布隆过滤器
容器运行时分析
监控容器运行时工具Falco
Chinatelecom has maintained a strong momentum in the mobile phone user market, but China Mobile has opened a new track
Sysdig analysis container system call
论文的英文文献在哪找(除了知网)?
開源了 | 文心大模型ERNIE-Tiny輕量化技術,又准又快,效果全開
随机推荐
Where can I find foreign papers?
Architecture: load balancing
洛谷_P1149 [NOIP2008 提高组] 火柴棒等式_枚举打表
Install docker and use docker to install MySQL
Digital twin smart factory develops digital twin factory solutions
Codeforces Round #771 (Div. 2)---A-D
Hit the industry directly! The propeller launched the industry's first model selection tool
Which software can translate an English paper in its entirety?
Bigder: how to deal with the bugs found in the 32/100 test if they are not bugs
Bloom filter
How much do you know about synchronized?
Sysdig analysis container system call
How to specify const array in the global scope of rust- How to specify const array in global scope in Rust?
洛谷_P2010 [NOIP2016 普及组] 回文日期_折半枚举
CADD课程学习(4)-- 获取没有晶体结构的蛋白(SWISS-Model)
Explain in detail the process of realizing Chinese text classification by CNN
Angled detection frame | calibrated depth feature for target detection (with implementation source code)
秒杀系统设计
Happy Lantern Festival, how many of these technical lantern riddles can you guess correctly?
Additional: token; (don't read until you finish writing...)