#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>
#include <wait.h>
#define ARRAY_KEY 1000
#define GET_KEY 2000
#define SUM_KEY 3000
#define SEM_KEY 4000
#define ARRAY_SIZE 5
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
void P(int semid, int index) {
struct sembuf sem_buf;
sem_buf.sem_num = index;
sem_buf.sem_op = -1;
sem_buf.sem_flg = 0;
semop(semid, &sem_buf, 1);
}
void V(int semid, int index) {
struct sembuf sem_buf;
sem_buf.sem_num = index;
sem_buf.sem_op = 1;
sem_buf.sem_flg = 0;
semop(semid, &sem_buf, 1);
}
int main() {
int shmid_array = shmget(ARRAY_KEY, ARRAY_SIZE * sizeof(int), IPC_CREAT | 0666);
int shmid_get = shmget(GET_KEY, sizeof(int), IPC_CREAT | 0666);
int shmid_sum = shmget(SUM_KEY, sizeof(int), IPC_CREAT | 0666);
int semid = semget(SEM_KEY, 3, IPC_CREAT | 0666);
union semun sem_union;
sem_union.val = 1;
semctl(semid, 0, SETVAL, sem_union);
sem_union.val = 0;
semctl(semid, 1, SETVAL, sem_union);
sem_union.val = 0;
semctl(semid, 2, SETVAL, sem_union);
pid_t pid1, pid2, pid3;
pid1 = fork();
if (pid1 == 0) {
int *array = (int *)shmat(shmid_array, NULL, 0);
for (int i = 1; i <= 10; i++) {
P(semid, 0);
array[(i - 1) % ARRAY_SIZE] = i;
V(semid, i % 2 == 0 ? 1 : 2);
}
exit(0);
}
pid2 = fork();
if (pid2 == 0) {
int *array = (int *)shmat(shmid_array, NULL, 0);
int *get = (int *)shmat(shmid_get, NULL, 0);
int *sum = (int *)shmat(shmid_sum, NULL, 0);
while (*get < 10) {
P(semid, 1);
if (*get < 10) {
*sum += array[*get % ARRAY_SIZE];
(*get)++;
V(semid, 0);
}
}
exit(0);
}
pid3 = fork();
if (pid3 == 0) {
int *array = (int *)shmat(shmid_array, NULL, 0);
int *get = (int *)shmat(shmid_get, NULL, 0);
int *sum = (int *)shmat(shmid_sum, NULL, 0);
while (*get < 10) {
P(semid, 2);
if (*get < 10) {
*sum += array[*get % ARRAY_SIZE];
(*get)++;
V(semid, 0);
}
}
exit(0);
}
waitpid(pid1, NULL, 0);
waitpid(pid2, NULL, 0);
waitpid(pid3, NULL, 0);
int *sum = (int *)shmat(shmid_sum, NULL, 0);
printf("累加和为:%d\n", *sum);
shmctl(shmid_array, IPC_RMID, NULL);
shmctl(shmid_get, IPC_RMID, NULL);
shmctl(shmid_sum, IPC_RMID, NULL);
semctl(semid, 0, IPC_RMID, NULL);
return 0;
}
最后由父进程输出累加和。父子进程间的同步互斥通过同步、互斥信号量的P、V操作实现。 提示:需要使用3个共享内存,使用共享内存array存放数据,使用共享内存get存放子进程2和3的读计数,使用共享内存sum存放读出数据的累加和。