linux生产者消费者模型源代码

找到一段蛮好的linux生产者消费者模型源代码,其中的mmap()未接触过,应该是较老版本的共享内存函数吧。
跟大家分享下:


模型:
  有两个生产者,一个写入大写字母,另一个写入小写。

有三个消费者,一个消费大写字母,一个消费小写字母,还有一个不分大小写消费。

#include <stdlib.h>
#include <sys/mman.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <linux/sem.h>
#include <sys/types.h>

#define MAX_PRODUCTS 10
struct sembuf buf;

int down(int sem_id)
{
    buf.sem_num = 0;
    buf.sem_op = -1;
    buf.sem_flg = SEM_UNDO;
    if (semop(sem_id, &buf, 1) == -1)
    {
        perror("Down failed!/n");
        return 0;
    }
    return 1;
}
int up(int sem_id)
{
    buf.sem_num = 0;
    buf.sem_op = 1;
    buf.sem_flg = SEM_UNDO;
    if (semop(sem_id, &buf, 1) == -1)
    {
        perror("Up failed!/n");
        return 0;
    }
    return 1;
}

void main()
{
    union semun arg;
    pid_t producer1, producer2;
    pid_t consumer1, consumer2, consumer3;

    int mutex;
    int full;
    int empty;
    char *buffer;

    // 共享内存
    buffer = (char*) mmap(NULL, sizeof(char) * MAX_PRODUCTS,
            PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
    int i;
    for (i = 0; i < MAX_PRODUCTS; i++)
        buffer[i] = '';

    // 创建信号量
    mutex = semget(IPC_PRIVATE, 1, 0666 | IPC_CREAT);
    full = semget(IPC_PRIVATE, 1, 0666 | IPC_CREAT);
    empty = semget(IPC_PRIVATE, 1, 0666 | IPC_CREAT);
    arg.val = 1;
    if (semctl(mutex, 0, SETVAL, arg) == -1)
    {
        perror("set the mutex error\n");
        return;
    }
    arg.val = 0;
    if (semctl(full, 0, SETVAL, arg) == -1)
    {
        perror("set the full error\n");
        return;
    }
    arg.val = MAX_PRODUCTS;
    if (semctl(empty, 0, SETVAL, arg) == -1)
    {
        perror("set the empty error/n");
        return;
    }

    if ((producer1 = fork()) == 0)
    {
        // 写入大写字母
        while (1)
        {
            down(empty);
            down(mutex);
            srand(time(NULL));
            int offset = rand() % 26;
            char item = 'A' + offset;
            int j;
            for (j = 0; j < MAX_PRODUCTS; j++)
            {
                if (buffer[j] == '')
                {
                    buffer[j] = item;
                    printf("Producer A insert letter: %c\n", item);
                    break;
                }
            }
            up(mutex);
            up(full);
            sleep(1);
        }
    }
    else if ((producer2 = fork()) == 0)
    {
        // 写入小写字母
        while (1)
        {
            down(empty);
            down(mutex);
            srand(time(NULL));
            int offset = rand() % 26;
            char item = 'a' + offset;
            int j;
            for (j = 0; j < MAX_PRODUCTS; j++)
            {
                if (buffer[j] == '')
                {
                    buffer[j] = item;
                    printf("Producer B insert letter: %c\n", item);
                    break;
                }
            }
            up(mutex);
            up(full);
            sleep(1);
        }
    }
    else if ((consumer1 = fork()) == 0)
    {
        // 消费大写字母
        while (1)
        {
            down(full);
            down(mutex);
            char item;
            int j;
            for (j = 0; j < MAX_PRODUCTS; j++)
            {
                if (buffer[j] >= 'A' && buffer[j] <= 'Z')
                {
                    item = buffer[j];
                    buffer[j] = '';
                    break;
                }
            }
            printf("Consumer A removes letter: %c\n", item);
            up(mutex);
            up(empty);
            sleep(2);
        }
    }
    else if ((consumer2 = fork()) == 0)
    {
        // 消费小写字母
        while (1)
        {
            down(full);
            down(mutex);
            char item;
            int j;
            for (j = 0; j < MAX_PRODUCTS; j++)
            {
                if (buffer[j] >= 'a' && buffer[j] <= 'z')
                {
                    item = buffer[j];
                    buffer[j] = '';
                    break;
                }
            }
            printf("Consumer B removes letter: %c\n", item);
            up(mutex);
            up(empty);
            sleep(2);
        }
    }
    else if ((consumer3 = fork()) == 0)
    {
        // 大小写字母
        while (1)
        {
            down(full);
            down(mutex);
            char item;
            int j;
            for (j = 0; j < MAX_PRODUCTS; j++)
            {
                if (buffer[j] != '')
                {
                    item = buffer[j];
                    buffer[j] = '';
                    break;
                }
            }
            printf("Consumer C removes letter: %c\n", item);
            up(mutex);
            up(empty);
            sleep(2);
        }
    }
    else
    {
        // 主进程
        while (1)
        {
            int j;
            printf("Buffer: ");
            for (j = 0; j < MAX_PRODUCTS; j++)
            {
                printf("%c ", buffer[j]);
            }
            printf(" \n");
            sleep(10);
        }
    }
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值