在Linux环境下,C++程序可以通过多种方式实现内存映射。以下是几种常用的方法:
mmap 系统调用mmap 是一个系统调用,用于将文件或设备映射到进程的地址空间。它也可以用于匿名映射(不对应任何文件)。
示例代码:
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
int main() {
// 打开一个文件
int fd = open("example.txt", O_RDONLY);
if (fd == -1) {
perror("open");
return 1;
}
// 获取文件大小
off_t length = lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);
// 映射文件到内存
void* addr = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0);
if (addr == MAP_FAILED) {
perror("mmap");
close(fd);
return 1;
}
// 使用映射的内存
std::cout << static_cast<char*>(addr) << std::endl;
// 解除映射
if (munmap(addr, length) == -1) {
perror("munmap");
}
close(fd);
return 0;
}
mmap 进行匿名映射匿名映射不对应任何文件,通常用于共享内存。
示例代码:
#include <sys/mman.h>
#include <unistd.h>
#include <iostream>
int main() {
// 创建匿名映射
void* addr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (addr == MAP_FAILED) {
perror("mmap");
return 1;
}
// 使用映射的内存
int* data = static_cast<int*>(addr);
*data = 42;
std::cout << "Data: " << *data << std::endl;
// 解除映射
if (munmap(addr, 4096) == -1) {
perror("munmap");
}
return 0;
}
POSIX 共享内存允许进程间共享内存区域。
示例代码(创建共享内存):
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
#include <string.h>
int main() {
const char* name = "/my_shm";
int shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
if (shm_fd == -1) {
perror("shm_open");
return 1;
}
// 设置共享内存大小
if (ftruncate(shm_fd, sizeof(int)) == -1) {
perror("ftruncate");
close(shm_fd);
shm_unlink(name);
return 1;
}
// 映射共享内存
void* addr = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (addr == MAP_FAILED) {
perror("mmap");
close(shm_fd);
shm_unlink(name);
return 1;
}
// 使用共享内存
int* data = static_cast<int*>(addr);
*data = 42;
std::cout << "Shared Data: " << *data << std::endl;
// 解除映射
if (munmap(addr, sizeof(int)) == -1) {
perror("munmap");
}
close(shm_fd);
shm_unlink(name);
return 0;
}
示例代码(访问共享内存):
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
#include <string.h>
int main() {
const char* name = "/my_shm";
int shm_fd = shm_open(name, O_RDONLY, 0666);
if (shm_fd == -1) {
perror("shm_open");
return 1;
}
// 映射共享内存
void* addr = mmap(NULL, sizeof(int), PROT_READ, MAP_SHARED, shm_fd, 0);
if (addr == MAP_FAILED) {
perror("mmap");
close(shm_fd);
shm_unlink(name);
return 1;
}
// 访问共享内存
int* data = static_cast<int*>(addr);
std::cout << "Shared Data: " << *data << std::endl;
// 解除映射
if (munmap(addr, sizeof(int)) == -1) {
perror("munmap");
}
close(shm_fd);
shm_unlink(name);
return 0;
}
boost::interprocessboost::interprocess 是一个跨平台的库,提供了丰富的内存管理功能,包括共享内存、内存映射文件等。
示例代码:
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <iostream>
#include <cstring>
namespace bip = boost::interprocess;
int main() {
// 创建或打开共享内存对象
bip::shared_memory_object shm(bip::open_or_create, "MySharedMemory", bip::read_write);
shm.truncate(sizeof(int));
// 映射共享内存
bip::mapped_region region(shm, bip::read_write);
void* addr = region.get_address();
// 使用映射的内存
int* data = static_cast<int*>(addr);
*data = 42;
std::cout << "Shared Data: " << *data << std::endl;
return 0;
}
以上方法各有优缺点,选择合适的方法取决于具体的应用场景和需求。mmap 系统调用提供了底层的内存映射功能,而 POSIX 共享内存和 boost::interprocess 则提供了更高层次的抽象,简化了共享内存的管理。