c++ 共享内存
1.1 共享内存的定义
共享内存是指多个进程可以同时访问和操作的一块内存空间。不同于进程间通信(IPC)中的消息传递方式,共享内存可以实现多个进程之间的数据共享,提高程序的效率。
1.2 共享内存的作用
共享内存可以用于同一台计算机上的多个进程之间进行数据的共享与交互。通过使用共享内存,可以避免数据的复制和传递所带来的时间消耗,提高程序的执行效率。
二、C++ 中的共享内存实现
2.1 C++ 中的共享内存概念
在 C++ 程序中,可以通过使用标准库 <sys/shm.h>
实现共享内存操作。该库提供了一系列的函数,用于创建、获取和使用共享内存。
2.2 C++ 中的共享内存实现步骤
使用 C++ 实现共享内存的步骤如下:
- 创建共享内存
- 把共享内存连接到当前进程的地址空间
- 进行读写操作
- 断开与共享内存的连接
- 删除共享内存
2.3 共享内存的创建和连接
首先,我们需要创建一块共享内存区域。使用 shmget()
函数可以创建一个共享内存 id。该函数的定义如下:
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
函数参数:
key
:共享内存的键值,用于唯一标识该块共享内存。size
:共享内存的大小,以字节为单位。shmflg
:创建共享内存的权限标志。
函数返回值:
- 成功时返回共享内存的 id。
- 失败时返回 -1,并设置错误码。
例如,下面的代码创建了一块大小为 1024 字节的共享内存:
#include <sys/ipc.h>
#include <sys/shm.h>
#include <iostream>
int main() {
key_t key = ftok(".", 'x'); // 生成共享内存的键值
int shm_id = shmget(key, 1024, IPC_CREAT | 0666); // 创建共享内存
if (shm_id == -1) {
std::cerr << "Failed to create shared memory" << std::endl;
return 1;
}
std::cout << "Shared memory created with id: " << shm_id << std::endl;
return 0;
}
运行结果如下:
Shared memory created with id: 12345
接下来,我们需要把共享内存连接到当前进程的地址空间。使用 shmat()
函数进行连接。该函数的定义如下:
void* shmat(int shmid, const void* shmaddr, int shmflg);
函数参数:
shmid
:共享内存的 id。shmaddr
:共享内存的起始地址,传入NULL
时表示由系统选择合适的地址。shmflg
:共享内存的连接标志。
函数返回值:
- 成功时返回指向共享内存区域的指针。
- 失败时返回
NULL
并设置错误码。
例如,下面的代码将共享内存连接到当前进程:
#include <sys/ipc.h>
#include <sys/shm.h>
#include <iostream>
int main() {
key_t key = ftok(".", 'x'); // 生成共享内存的键值
int shm_id = shmget(key, 1024, IPC_CREAT | 0666); // 创建共享内存
if (shm_id == -1) {
std::cerr << "Failed to create shared memory" << std::endl;
return 1;
}
void* shared_mem = shmat(shm_id, NULL, 0); // 连接共享内存
if (shared_mem == (void*)-1) {
std::cerr << "Failed to attach shared memory" << std::endl;
return 1;
}
std::cout << "Shared memory attached at address: " << shared_mem << std::endl;
return 0;
}
运行结果如下:
Shared memory created with id: 12345
Shared memory attached at address: 0x7f9a6a195000
2.4 共享内存的读写操作
连接到共享内存后,我们可以使用普通的指针操作来访问共享内存。可以通过对指针的读写操作实现与其他进程之间的数据共享。
例如,下面的代码演示了两个进程之间的数据共享。一个进程写入数据到共享内存,另一个进程读取并修改数据:
进程1:
#include <sys/ipc.h>
#include <sys/shm.h>
#include <iostream>
int main() {
key_t key = ftok(".", 'x'); // 生成共享内存的键值
int shm_id = shmget(key, 1024, IPC_CREAT | 0666); // 创建共享内存
if (shm_id == -1) {
std::cerr << "Failed to create shared memory" << std::endl;
return 1;
}
void* shared_mem = shmat(shm_id, NULL, 0); // 连接共享内存
if (shared_mem == (void*)-1) {
std::cerr << "Failed to attach shared memory" << std::endl;
return 1;
}
int* data = (int*)shared_mem;
*data = 100; // 写入数据
std::cout << "Data written: " << *data << std::endl;
shmdt(shared_mem); // 断开与共享内存的连接
return 0;
}
进程2:
#include <sys/ipc.h>
#include <sys/shm.h>
#include <iostream>
int main() {
key_t key = ftok(".", 'x'); // 生成共享内存的键值
int shm_id = shmget(key, 1024, IPC_CREAT | 0666); // 创建共享内存
if (shm_id == -1) {
std::cerr << "Failed to create shared memory" << std::endl;
return 1;
}
void* shared_mem = shmat(shm_id, NULL, 0); // 连接共享内存
if (shared_mem == (void*)-1) {
std::cerr << "Failed to attach shared memory" << std::endl;
return 1;
}
int* data = (int*)shared_mem;
std::cout << "Data read: " << *data << std::endl;
*data = 200; // 修改数据
std::cout << "Data modified: " << *data << std::endl;
shmdt(shared_mem); // 断开与共享内存的连接
return 0;
}
以上代码中,进程1将数据写入共享内存