在 Linux 系统中,多进程同步(Inter-Process Communication, IPC)是确保多个进程有序访问共享资源或协调工作的关键。以下是常见的多进程同步方法及其特点:
semget
, semop
, semctl
。sem_init
, sem_wait
, sem_post
(更轻量)。c
#include <semaphore.h>
sem_t *sem = sem_open("/mysem", O_CREAT, 0644, 1); // 初始化值为1
sem_wait(sem); // P操作(获取锁)
// 临界区代码
sem_post(sem); // V操作(释放锁)
fcntl
(更灵活):支持记录锁(锁定文件部分内容)。flock
:锁定整个文件。c
int fd = open("/tmp/lockfile", O_RDWR);
flock(fd, LOCK_EX); // 加排他锁
// 临界区代码
flock(fd, LOCK_UN); // 解锁
shmget
或 mmap
。shmat
。c
// 共享内存 + POSIX信号量
int shm_id = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666);
int *ptr = shmat(shm_id, NULL, 0);
sem_init(&sem, 1, 1); // 进程间信号量需放在共享内存中
sem_wait(&sem);
*ptr += 1; // 安全修改
sem_post(&sem);
pthread_mutexattr_setpshared
)。c
pthread_mutex_t *mutex = mmap(NULL, sizeof(pthread_mutex_t), PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_ANONYMOUS, -1, 0);
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(mutex, &attr);
pthread_mutex_lock(mutex);
// 临界区代码
pthread_mutex_unlock(mutex);
pipe()
,仅限父子进程。mkfifo
,无亲缘关系进程可用。msgget
, msgsnd
, msgrcv
(System V 或 POSIX)。bash
# 命名管道同步示例
mkfifo /tmp/myfifo
# 进程1
echo "data" > /tmp/myfifo
# 进程2
cat /tmp/myfifo
pthread_barrier
(需配合共享内存用于进程间)。场景 | 推荐方法 |
---|---|
高效共享数据 | 共享内存 + 信号量/互斥锁 |
简单进程同步 | 文件锁或信号量 |
无亲缘关系进程通信 | 命名管道/FIFO 或 System V IPC |
复杂条件等待 | 条件变量 + 互斥锁(需共享内存) |
sem_wait
),需处理EINTR
。通过合理选择同步机制,可以高效解决 Linux 多进程协作问题。