在Linux环境下,当多个进程需要共享内存并进行互斥访问时,通常会使用POSIX共享内存和POSIX互斥锁(mutexes)或信号量(semaphores)来实现。这里,我将通过一个简单的C语言示例来说明如何使用POSIX共享内存和POSIX互斥锁来控制对共享内存段的访问。
步骤 1: 包含必要的头文件
首先,需要包含处理共享内存和互斥锁的头文件。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <pthread.h> // 注意:虽然名字中有pthread,但POSIX互斥锁也在这里定义
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
步骤 2: 定义共享内存和互斥锁
#define SHM_NAME "/my_shared_memory"
#define SHM_SIZE 4096
int shm_fd;
void *ptr;
pthread_mutex_t lock;
// 初始化共享内存和互斥锁
void init_shm_and_lock() {
// 创建或打开共享内存对象
shm_fd = shm_open(SHM_NAME, O_CREAT | O_RDWR, 0666);
if (shm_fd == -1) {
perror("shm_open");
exit(EXIT_FAILURE);
}
// 设置共享内存的大小
ftruncate(shm_fd, SHM_SIZE);
// 映射共享内存到进程地址空间
ptr = mmap(0, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (ptr == MAP_FAILED) {
perror("mmap");
exit(EXIT_FAILURE);
}
// 初始化互斥锁
if (pthread_mutex_init(&lock, NULL) != 0) {
perror("pthread_mutex_init");
exit(EXIT_FAILURE);
}
}
// 清理资源
void cleanup() {
pthread_mutex_destroy(&lock);
munmap(ptr, SHM_SIZE);
close(shm_fd);
shm_unlink(SHM_NAME);
}
步骤 3: 访问共享内存的函数
void write_to_shm(const char *str) {
pthread_mutex_lock(&lock);
memcpy(ptr, str, strlen(str) + 1);
printf("Written to shared memory: %s\n", (char *)ptr);
pthread_mutex_unlock(&lock);
}
void read_from_shm() {
pthread_mutex_lock(&lock);
printf("Read from shared memory: %s\n", (char *)ptr);
pthread_mutex_unlock(&lock);
}
步骤 4: 示例使用
int main() {
init_shm_and_lock();
// 第一个进程写入
write_to_shm("Hello, Shared Memory!");
// 第二个进程读取(在同一个程序中模拟)
sleep(1); // 等待写入完成
read_from_shm();
cleanup();
return 0;
}
注意
- 这个示例在单个程序中模拟了多个进程对共享内存的访问,但在真实的多进程环境中,每个进程都需要独立地执行
init_shm_and_lock()
和cleanup()
函数(或者类似的函数)来初始化其自己的共享内存和互斥锁句柄。 - POSIX互斥锁和共享内存对象在Linux中是通过文件系统(通常是
/dev/shm
或/run/shm
)实现的,因此它们对于同一台机器上的多个进程是可见的。 - 错误处理和资源清理非常重要,以确保系统的稳定性和安全性。
- 在真实应用中,可能需要更复杂的同步机制,如条件变量或读写锁,以优化性能和减少等待时间。