semop实现两个进程读写共享内存,使用信号量同步,while循环
时间: 2023-11-18 17:04:47 浏览: 182
下面是一个使用 `semop` 实现两个进程读写共享内存,使用信号量同步,使用 while 循环的例子:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#define SHM_SIZE 1024
#define SEM_KEY 1234
#define SHM_KEY 5678
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
void sem_wait(int sem_id, int sem_num) {
struct sembuf sb;
sb.sem_num = sem_num;
sb.sem_op = -1;
sb.sem_flg = 0;
semop(sem_id, &sb, 1);
}
void sem_signal(int sem_id, int sem_num) {
struct sembuf sb;
sb.sem_num = sem_num;
sb.sem_op = 1;
sb.sem_flg = 0;
semop(sem_id, &sb, 1);
}
int main() {
int shmid, semid;
char *shm_ptr;
union semun sem_init_val;
struct sembuf sb[2];
// 创建共享内存
if ((shmid = shmget(SHM_KEY, SHM_SIZE, IPC_CREAT | 0666)) < 0) {
perror("shmget");
exit(1);
}
// 连接共享内存
if ((shm_ptr = shmat(shmid, NULL, 0)) == (char *) -1) {
perror("shmat");
exit(1);
}
// 创建信号量
if ((semid = semget(SEM_KEY, 2, IPC_CREAT | 0666)) < 0) {
perror("semget");
exit(1);
}
// 初始化信号量
sem_init_val.val = 0; // 读信号量初始值为 0
semctl(semid, 0, SETVAL, sem_init_val);
sem_init_val.val = 1; // 写信号量初始值为 1
semctl(semid, 1, SETVAL, sem_init_val);
// 操作信号量
sb[0].sem_num = 0; // 读信号量
sb[0].sem_op = -1;
sb[0].sem_flg = 0;
sb[1].sem_num = 1; // 写信号量
sb[1].sem_op = 1;
sb[1].sem_flg = 0;
// 创建子进程
pid_t pid;
if ((pid = fork()) < 0) {
perror("fork");
exit(1);
}
if (pid == 0) { // 子进程
while (1) {
sem_wait(semid, 0); // 等待读信号量
printf("child read: %s\n", shm_ptr);
sem_signal(semid, 1); // 发送写信号量
}
} else { // 父进程
while (1) {
sem_wait(semid, 1); // 等待写信号量
printf("parent write: ");
scanf("%s", shm_ptr);
sem_signal(semid, 0); // 发送读信号量
}
}
// 删除共享内存和信号量
shmdt(shm_ptr);
shmctl(shmid, IPC_RMID, NULL);
semctl(semid, 0, IPC_RMID, sem_init_val);
return 0;
}
```
在这个例子中,我们创建了一个大小为 1024 的共享内存和两个信号量,一个用于读操作,一个用于写操作。父进程负责写入数据到共享内存,子进程负责读取并显示数据。
父进程等待写信号量,然后从标准输入读取用户输入的数据,将数据写入共享内存,并向读信号量发出信号。子进程等待读信号量,从共享内存中读取数据并显示,然后向写信号量发出信号。
注意,在使用共享内存和信号量时,需要使用 `semop` 函数进行操作。在 `semop` 函数中,我们需要指定信号量的标识符、要操作的信号量的编号和操作(加/减操作)等参数。由于在多进程程序中,信号量的值可能会被多个进程同时修改,因此在对信号量进行操作时需要使用临界区和互斥机制来保证操作的正确性。在这个例子中,我们使用了 `sem_wait` 和 `sem_signal` 函数来实现临界区和互斥机制。
阅读全文