semop实现多进程读写共享内存,使用信号量同步
时间: 2023-12-26 22:03:35 浏览: 98
在多进程读写共享内存时,我们可以使用信号量来保证进程之间的同步。信号量是一种系统资源,它可以用来控制进程的访问和使用共享资源的次数。
在Linux系统中,使用semget函数创建一个信号量集合,使用semop函数对信号量进行操作。semop函数可以实现信号量的P操作和V操作,P操作将信号量的值减1,V操作将信号量的值加1。
下面是一个简单的使用semop函数实现多进程读写共享内存的示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#define KEY 1234
#define SEM_KEY 4321
int main() {
int semid, shmid, *shm;
struct sembuf sem_p, sem_v;
pid_t pid;
// 创建信号量集合
semid = semget(SEM_KEY, 1, IPC_CREAT | 0666);
if (semid == -1) {
perror("semget error");
exit(1);
}
// 初始化信号量
if (semctl(semid, 0, SETVAL, 1) == -1) {
perror("semctl error");
exit(1);
}
// 创建共享内存
shmid = shmget(KEY, sizeof(int), IPC_CREAT | 0666);
if (shmid == -1) {
perror("shmget error");
exit(1);
}
// 映射共享内存
shm = (int *)shmat(shmid, NULL, 0);
if (shm == (int *)-1) {
perror("shmat error");
exit(1);
}
*shm = 0;
pid = fork();
if (pid == -1) {
perror("fork error");
exit(1);
} else if (pid == 0) {
// 子进程写入共享内存
sem_p.sem_num = 0;
sem_p.sem_op = -1;
sem_p.sem_flg = SEM_UNDO;
semop(semid, &sem_p, 1);
printf("Child process write %d\n", ++(*shm));
sem_v.sem_num = 0;
sem_v.sem_op = 1;
sem_v.sem_flg = SEM_UNDO;
semop(semid, &sem_v, 1);
exit(0);
} else {
// 父进程读取共享内存
sem_p.sem_num = 0;
sem_p.sem_op = -1;
sem_p.sem_flg = SEM_UNDO;
semop(semid, &sem_p, 1);
printf("Parent process read %d\n", *shm);
sem_v.sem_num = 0;
sem_v.sem_op = 1;
sem_v.sem_flg = SEM_UNDO;
semop(semid, &sem_v, 1);
wait(NULL);
}
// 解除共享内存映射
if (shmdt(shm) == -1) {
perror("shmdt error");
exit(1);
}
// 删除共享内存
if (shmctl(shmid, IPC_RMID, 0) == -1) {
perror("shmctl error");
exit(1);
}
// 删除信号量集合
if (semctl(semid, 0, IPC_RMID, 0) == -1) {
perror("semctl error");
exit(1);
}
return 0;
}
```
在上面的示例中,我们创建了一个信号量集合和一个共享内存。父进程读取共享内存,子进程写入共享内存,两个进程都使用了信号量来保证同步。
在写入共享内存之前,子进程使用P操作将信号量的值减1,如果信号量的值为0,则子进程会阻塞等待。当子进程写入共享内存之后,它使用V操作将信号量的值加1,这样父进程就可以继续读取共享内存了。
在读取共享内存之前,父进程也使用P操作将信号量的值减1,如果信号量的值为0,则父进程会阻塞等待。当父进程读取共享内存之后,它使用V操作将信号量的值加1,这样子进程就可以继续写入共享内存了。
需要注意的是,使用信号量来保证进程之间的同步时,要确保每个进程都正确地使用P操作和V操作,否则可能会导致死锁或者竞争条件。
阅读全文