我们承担ROS,FastDDS等中间件以及C++,cmake等技术的项目开发和专业指导和培训,有10年+工作经验,质量有保证,如有需要请私信联系。
Linux共享内存是一种进程间通信的方式,让不同的进程可以访问同一块内存区域。这样,一个进程可以直接读取或者修改另一进程的数据,避免了数据的复制,提高了通信效率。
Linux中的共享内存被组织成一种名为“段”(segment)的数据结构,每个段都有一个全系统唯一的键值。进程可以通过这个键值来获取相应的内存段。
Linux支持两种类型的共享内存:System V IPC共享内存和POSIX共享内存
共享内存涉及到的主要操作有创建和连接共享内存、读写共享内存和断开和删除共享内存。
另外,由于共享内存涉及到多个进程对同一块内存区域的访问,因此,在对共享内存进行读写时需要注意同步和互斥的问题,防止数据被同时修改,导致数据混乱。
System V IPC共享内存
这是早期UNIX系统引入的传统共享内存方式,通过ipc函数(如shmget, shmat等)进行操作。
POSIX共享内存
POSIX共享内存:相比于System V IPC共享内存,POSIX共享内存的接口更简单,而且性能也更好。其共享内存的创建和管理则更像是文件操作,通过mmap等函数进行操作,而且支持有名字的共享内存,这样就可以通过名字来让不相关的进程共享内存。
POSIX共享内存在Linux系统中,是通过内存映射的方式实现的。具体来说,它会在虚拟内存空间中创建一块区域,并将其映射到物理内存,这样就形成了一个共享内存区域。然后,不同的进程可以将这块共享内存区域映射到自己的地址空间中,这样就可以访问和修改这块共享内存。
创建和使用POSIX共享内存的步骤如下:
创建共享内存:可以使用shm_open函数创建一个新的共享内存段或者打开一个已存在的共享内存段。这个函数会返回一个文件描述符,后续的操作都会用到这个文件描述符。
设置共享内存大小:可以使用ftruncate函数设置共享内存的大小。需要注意的是,刚创建的共享内存大小为0,必须通过ftruncate设定大小后才能使用。
映射共享内存:可以使用mmap函数将共享内存映射到进程的地址空间,返回映射地址。之后进程就可以通过这个地址来访问共享内存。
操作共享内存:进程可以直接通过前一步得到的地址来读写共享内存。
解除映射:当进程不再需要使用共享内存时,应使用munmap函数将共享内存从自己的地址空间中解除映射。
删除共享内存:如果系统中不再需要这块共享内存,可以使用shm_unlink函数删除它。
因此,POSIX共享内存的关键在于内存映射,通过在虚拟内存和物理内存之间建立映射关系,使得不同的进程都可以访问同一块物理内存。这样不仅提高了数据访问的效率,而且简化了进程间的通信。
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define SHM_NAME "/my_shm"
#define SHM_SIZE 1024
int main() {
int shm_fd;
void *ptr;
/* 创建共享内存对象 */
shm_fd = shm_open(SHM_NAME, O_CREAT | O_RDWR, 0666);
if (shm_fd == -1) {
perror("shm_open");
exit(-1);
}
/* 设置共享内存的大小 */
if (ftruncate(shm_fd, SHM_SIZE) == -1) {
perror("ftruncate");
exit(-1);
}
/* 映射共享内存 */
ptr = mmap(0, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (ptr == MAP_FAILED) {
perror("mmap");
exit(-1);
}
/* 在父进程中写入数据,子进程中读取数据 */
if (fork() == 0) {
/* Child process */
sleep(1); /* Wait for a while to make sure the parent process has written the data. */
printf("Child read: %s\n", (char*)ptr);
munmap(ptr, SHM_SIZE);
shm_unlink(SHM_NAME);
} else {
/* Parent process */
const char *message = "Hello, Shared Memory!";
sprintf(ptr, "%s", message);
printf("Parent wrote: %s\n", (char*)ptr);
sleep(2); /* Wait for a while to make sure the child process has read the data. */
munmap(ptr, SHM_SIZE);
}
return 0;
}
标签:SHM,映射,shm,Linux,进程,共享内存,ptr
From: https://blog.csdn.net/qq_44624290/article/details/140227921