#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sys/stat.h>
#include <string>
#include <iostream>
/*
这些函数属于 POSIX 共享内存 API,定义在 librt 库中。在编译和链接时,需要显式地链接 librt 库。
target_link_libraries(${TagetName} rt)
*/
int CreateSharedMemory(int *fd , std::string shared_mem_name)
{
// 创建并打开共享内存对象
*fd = shm_open(shared_mem_name.c_str(), O_CREAT | O_RDWR | O_EXCL, 0666);
// O_RDONLY: 以只读方式打开共享内存对象。
// O_RDWR: 以读写方式打开共享内存对象。
// O_CREAT: 如果共享内存对象不存在,则创建它。
// O_EXCL: 如果指定了 O_CREAT 并且共享内存对象已经存在,则返回错误。
// O_TRUNC: 如果共享内存对象已经存在,并且以可写方式打开,则将其长度截断为0
// 0666: 共享内存对象的权限(八进制),表示所有用户可读写。
if(*fd == -1)
{
if(errno == EEXIST)
{
shm_unlink(shared_mem_name.c_str());
}
perror("shm_open");
exit(EXIT_FAILURE);
}
return 0;
}
int SetSharedMemoryObjectSize(int fd , size_t mem_size, std::string shared_mem_name)
{
// 设置共享内存对象的大小
if (ftruncate(fd, mem_size) == -1) {
shm_unlink(shared_mem_name.c_str());
perror("ftruncate");
exit(EXIT_FAILURE);
}
return 0;
}
void * MappingSharedMemoryObjects(int fd , size_t mem_size, std::string shared_mem_name)
{
// 映射共享内存对象
void *ptr = mmap(NULL, mem_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (ptr == MAP_FAILED) {
perror("mmap");
shm_unlink(shared_mem_name.c_str());
exit(EXIT_FAILURE);
}
return ptr;
}
int UnmappingSharedMemoryObjects(void *ptr , size_t mem_size, std::string shared_mem_name)
{
// 解除映射共享内存对象
if (munmap(ptr, mem_size) == -1) {
perror("munmap");
shm_unlink(shared_mem_name.c_str());
exit(EXIT_FAILURE);
}
return 0;
}
int CloseSharedMemoryObject(int fd , size_t mem_size, std::string shared_mem_name)
{
// 关闭共享内存对象
if (close(fd) == -1) {
perror("close");
shm_unlink(shared_mem_name.c_str());
exit(EXIT_FAILURE);
}
return 0;
}
int DeleteSharedMemoryObject(int fd , size_t mem_size, std::string shared_mem_name)
{
// 删除共享内存对象
if (shm_unlink(shared_mem_name.c_str()) == -1) {
perror("shm_unlink");
exit(EXIT_FAILURE);
}
return 0;
}
int main(int argc, char** argv)
{
std::string mem_name{"/MY_SHM"};
size_t mem_size = sysconf(_SC_PAGE_SIZE) * 2;
std::cout << "mem_Size = " << mem_size << std::endl;
int fd;
// 创建并打开共享内存对象
CreateSharedMemory(&fd,mem_name);
// 设置共享内存对象的大小
SetSharedMemoryObjectSize(fd, mem_size, mem_name);
// 映射共享内存对象
void *ptr = MappingSharedMemoryObjects(fd, mem_size, mem_name);
// 使用共享内存对象
// 例如,将字符串写入共享内存
sprintf(static_cast<char *> (ptr), "Hello, Shared Memory!");
std::cout << "Read from shared memory: "<< std::string((char *)ptr) << std::endl;
// 解除映射共享内存对象
UnmappingSharedMemoryObjects(ptr, mem_size, mem_name);
// 关闭共享内存对象
CloseSharedMemoryObject(fd, mem_size, mem_name);
// 删除共享内存对象
DeleteSharedMemoryObject(fd, mem_size, mem_name);
printf("Shared memory object closed and unlinked successfully.\n");
return 0;
}
查看共享内存内容
hexdump -x /dev/shm/TankControlStat
print:
0000000 0001 0000
0000004
explan:
0000000 #文件起始偏移量 0001 # 后四个字节 0000 # 前三个字节
0000004 #文件终止偏移量(4个字节)