Bounded buffer (producer / consumer) problem solution with pthreads

 pc2.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

#define BUFFER_SIZE 12

typedef struct buffer {
    unsigned int count;
    unsigned int data[BUFFER_SIZE];
    int in;
    int out;
    pthread_mutex_t mutex;
    pthread_cond_t empty;
    pthread_cond_t full;
} buffer_t;

static buffer_t shared_buffer = {
    .count = 0,
    .in = 0,
    .out = 0,
    .mutex = PTHREAD_MUTEX_INITIALIZER,
    .empty = PTHREAD_COND_INITIALIZER,
    .full = PTHREAD_COND_INITIALIZER
};

static int
next()
{
    static unsigned int cnt = 0;
    return ++cnt;
}

static void
check(unsigned int num)
{
    static unsigned int cnt = 0;
    if (num != ++cnt) {
        fprintf(stderr, "oops: expected %u but got %u\n", cnt, num);
    }
}

static void*
producer(void *data)
{
    buffer_t *buffer = (buffer_t *) data;
    int i;
    while (1) {
        pthread_mutex_lock(&buffer->mutex);
        while (buffer->count == BUFFER_SIZE) {
            pthread_cond_wait(&buffer->empty, &buffer->mutex);
        }
        buffer->data[buffer->in] = next();
        printf("producer: %d\n", buffer->data[buffer->in]);
        buffer->in = (buffer->in + 1) % BUFFER_SIZE;
        buffer->count++;
        pthread_cond_signal(&buffer->full);
        pthread_mutex_unlock(&buffer->mutex);
    }
    return NULL;
}

static void*
consumer(void *data)
{
    buffer_t *buffer = (buffer_t *) data;
    int i;
    while (1) {
        pthread_mutex_lock(&buffer->mutex);
        while (buffer->count == 0) {
            pthread_cond_wait(&buffer->full, &buffer->mutex);
        }
        printf("consumer: %d\n", buffer->data[buffer->out]);
        check(buffer->data[buffer->out]);
        buffer->out = (buffer->out + 1) % BUFFER_SIZE;
        buffer->count--;
        pthread_cond_signal(&buffer->empty);
        pthread_mutex_unlock(&buffer->mutex);
    }
    return NULL;
}

static int
run(int nc, int np)
{
    int i, n = nc + np;

    pthread_t thread[n];

    for (i = 0; i < n; i++) {
        if (pthread_create(&thread[i], NULL,
                    i < nc ? consumer : producer, &shared_buffer)) {
            fprintf(stderr, "thread creation failed\n");
            return EXIT_FAILURE;
        }
    }

    for (i = 0; i < n; i++) {
        if (thread[i]) pthread_join(thread[i], NULL);
    }

    return EXIT_SUCCESS;
}

int
main(int argc, char **argv)
{
    int c, nc = 1, np = 1;
    const char *usage
        = "Usage: bounded [-c consumers] [-p producers] [-h]\n";
    while ((c = getopt(argc, argv, "c:p:h")) >= 0) {
        switch (c) {
            case 'c':
                if ((nc = atoi(optarg)) <= 0) {
                    fprintf(stderr, "number of consumers must be > 0\n");
                    exit(EXIT_FAILURE);
                }
                break;
            case 'p':
                if ((np = atoi(optarg)) <= 0) {
                    fprintf(stderr, "number of producers must be > 0\n");
                    exit(EXIT_FAILURE);
                }
                break;
            case 'h':
                printf(usage);
                exit(EXIT_SUCCESS);
        }
    }
    return run(nc, np);
}

 

转载于:https://my.oschina.net/tsh/blog/1499583

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值