353535

#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 <string.h>

#define SHM_KEY 1234

#define SEM_KEY 5678

struct BufferPool

{

    char Buffer[5][100];

    int Index[5];

};

// 定义信号量操作结构体

struct sembuf sem_lock = {0, -1, SEM_UNDO};

struct sembuf sem_unlock = {0, 1, SEM_UNDO};

void producer(int shmid, int semid, const char *inputFile)

{

    struct BufferPool *buffer = (struct BufferPool *)shmat(shmid, NULL, 0);

    FILE *input = fopen(inputFile, "r");

    char line[100];

    while (fgets(line, sizeof(line), input) != NULL)

    {

        // 等待可用的缓冲区

        semop(semid, &sem_lock, 1);

        // 查找可用的缓冲区

        int i;

        for (i = 0; i < 5; i++)

        {

            if (buffer->Index[i] == 0)

                break;

        }

        // 写入数据到缓冲区

        strcpy(buffer->Buffer[i], line);

        buffer->Index[i] = 1;

        printf("Producer: Wrote \"%s\" to buffer %d\n", line, i);

        // 释放缓冲区的访问权

        semop(semid, &sem_unlock, 1);

    }

    fclose(input);

    shmdt(buffer);

}

void consumer(int shmid, int semid, const char *outputFile)

{

    struct BufferPool *buffer = (struct BufferPool *)shmat(shmid, NULL, 0);

    FILE *output = fopen(outputFile, "w");

    while (1)

    {

        // 等待可消费的缓冲区

        semop(semid, &sem_lock, 1);

        // 查找可消费的缓冲区

        int i;

        for (i = 0; i < 5; i++)

        {

            if (buffer->Index[i] == 1)

                break;

        }

        // 读取数据并写入输出文件

        fputs(buffer->Buffer[i], output);

        printf("Consumer: Read \"%s\" from buffer %d\n", buffer->Buffer[i], i);

        // 重置缓冲区状态

        buffer->Index[i] = 0;

        // 释放缓冲区的访问权

        semop(semid, &sem_unlock, 1);

        // 结束条件:如果所有缓冲区都已经被消费,则退出循环

        int allConsumed = 1;

        for (i = 0; i < 5; i++)

        {

            if (buffer->Index[i] == 1)

            {

                allConsumed = 0;

                break;

            }

        }

        if (allConsumed)

            break;

    }

    fclose(output);

    shmdt(buffer);

}

int main()

{

    int shmid, semid;

    key_t key;

    const char *inputFile = "input.txt";

    const char *outputFile = "output.txt";

    // 创建共享内存

    key = ftok(".", SHM_KEY);

    shmid = shmget(key, sizeof(struct BufferPool), IPC_CREAT | 0666);

    if (shmid == -1)

    {

        perror("shmget");

        exit(1);

    }

    // 创建信号量集

    key = ftok(".", SEM_KEY);

    semid = semget(key, 1, IPC_CREAT | 0666);

    if (semid == -1)

    {

        perror("semget");

        exit(1);

    }

    // 初始化信号量

    semctl(semid, 0, SETVAL, 1);

    // 创建子进程

    pid_t pid = fork();

    if (pid == -1)

    {

        perror("fork");

        exit(1);

    }

    else if (pid == 0)

    {

        // 子进程作为第一个生产者

        producer(shmid, semid, inputFile);

        exit(0);

    }

    // 创建另一个子进程

    pid_t pid2 = fork();

    if (pid2 == -1)

    {

        perror("fork");

        exit(1);

    }

    else if (pid2 == 0)

    {

        // 另一个子进程作为第二个生产者

        producer(shmid, semid, inputFile);

        exit(0);

    }

    // 父进程作为第一个消费者

    consumer(shmid, semid, outputFile);

    // 等待子进程结束

    waitpid(pid, NULL, 0);

    waitpid(pid2, NULL, 0);

    // 删除共享内存和信号量集

    shmctl(shmid, IPC_RMID, NULL);

    semctl(semid, 0, IPC_RMID);

    return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值