面试题答案
一键面试共享内存机制在进程通信中的工作原理
共享内存允许不同进程访问同一块物理内存区域。操作系统负责将该物理内存映射到各个进程的虚拟地址空间中。这样,多个进程就可以直接读写这块共享区域的数据,实现高效的数据交互。这种方式避免了数据在进程间多次复制(如管道通信那样),大大提高了通信效率。然而,由于多个进程可以同时访问共享内存,可能会引发竞态条件等问题,通常需要结合其他同步机制(如信号量)来保证数据的一致性和完整性。
在生产者 - 消费者模型中使用共享内存实现进程间数据传递的示例(以C语言为例,基于POSIX共享内存)
- 创建共享内存对象
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/mman.h> #include <unistd.h> #include <semaphore.h> #define SHM_SIZE 1024 int main() { int shm_fd; void *ptr; // 创建共享内存对象 shm_fd = shm_open("/my_shared_memory", 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); }
- 生产者进程(示例)
pid_t pid = fork(); if (pid == 0) { // 子进程作为生产者 char message[] = "Hello, consumer!"; // 假设这里有一个同步机制(信号量)来保证数据一致性,这里先省略具体实现 // 生产者向共享内存写入数据 sprintf((char *)ptr, "%s", message); exit(0); }
- 消费者进程(示例)
else if (pid > 0) { // 父进程作为消费者 wait(NULL); // 消费者从共享内存读取数据 printf("Consumer read: %s\n", (char *)ptr); // 解除映射 if (munmap(ptr, SHM_SIZE) == -1) { perror("munmap"); exit(1); } // 关闭共享内存对象 if (close(shm_fd) == -1) { perror("close"); exit(1); } // 删除共享内存对象 if (shm_unlink("/my_shared_memory") == -1) { perror("shm_unlink"); exit(1); } } return 0; }
在这个简单示例中,生产者进程向共享内存写入数据,消费者进程从共享内存读取数据。实际应用中,通常需要使用信号量等同步机制来确保生产者和消费者不会同时访问共享内存,避免数据竞争和不一致的问题。