使用信号量实现进程的同步互斥混合关系

#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;
}

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值