#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 SHARED_MEMORY_SIZE 5
// 定义信号量操作结构体
struct sembuf P = {0, -1, SEM_UNDO};
struct sembuf V = {0, 1, SEM_UNDO};
void child1(int *array) {
int i;
for (i = 1; i <= 10; i++) {
array[i % SHARED_MEMORY_SIZE] = i;
}
}
void child2(int *array, int *get, int *sum, int sem_id) {
int i;
for (i = 0; i < 10; i++) {
semop(sem_id, &P, 1); // P操作
sum[i % SHARED_MEMORY_SIZE] = array[i % SHARED_MEMORY_SIZE];
semop(sem_id, &V, 1); // V操作
}
}
int child3(int *array, int *get, int *sum, int sem_id) {
int i, total_sum = 0;
for (i = 0; i < 10; i++) {
while (get[i % SHARED_MEMORY_SIZE] != 1) {
// 等待子进程2完成读取
}
total_sum += sum[i % SHARED_MEMORY_SIZE];
get[(i+1) % SHARED_MEMORY_SIZE] = 1;
}
return total_sum;
}
int main() {
int shmid_array, shmid_get, shmid_sum, sem_id;
int *array, *get, *sum;
int total_sum;
// 创建共享内存
shmid_array = shmget(IPC_PRIVATE, SHARED_MEMORY_SIZE * sizeof(int), IPC_CREAT | 0666);
shmid_get = shmget(IPC_PRIVATE, SHARED_MEMORY_SIZE * sizeof(int), IPC_CREAT | 0666);
shmid_sum = shmget(IPC_PRIVATE, SHARED_MEMORY_SIZE * sizeof(int), IPC_CREAT | 0666);
// 创建信号量
sem_id = semget(IPC_PRIVATE, 1, IPC_CREAT | 0666);
semctl(sem_id, 0, SETVAL, 1); // 初始化信号量为1
// 连接共享内存
array = (int *)shmat(shmid_array, 0, 0);
get = (int *)shmat(shmid_get, 0, 0);
sum = (int *)shmat(shmid_sum, 0, 0);
// 初始化共享内存
int i;
for (i = 0; i < SHARED_MEMORY_SIZE; i++) {
get[i] = 0;
sum[i] = 0;
}
// 创建子进程
pid_t pid1, pid2, pid3;
pid1 = fork();
if (pid1 == 0) {
child1(array);
exit(0);
}
pid2 = fork();
if (pid2 == 0) {
child2(array, get, sum, sem_id);
exit(0);
}
pid3 = fork();
if (pid3 == 0) {
total_sum = child3(array, get, sum, sem_id);
exit(total_sum);
}
// 等待子进程结束
waitpid(pid1, NULL, 0);
waitpid(pid2, NULL, 0);
waitpid(pid3, &total_sum, 0);
total_sum = WEXITSTATUS(total_sum);
// 输出累加和
printf("累加和:%d\n", total_sum);
// 删除共享内存
shmctl(shmid_array, IPC_RMID, 0);
shmctl(shmid_get, IPC_RMID, 0);
shmctl(shmid_sum, IPC_RMID, 0);
// 删除信号量
semctl(sem_id, 0, IPC_RMID, 0);
return 0;
}
使用信号量实现进程的同步互斥混合关系
最新推荐文章于 2024-08-20 14:34:44 发布