生产者消费者问题的pthread模拟

来源:互联网 发布:飞跃淘宝店铺信息软件 编辑:程序博客网 时间:2024/04/28 13:37

操作系统概念第七版上第六章的项目“生产者-消费者问题”的解答。
采用了三个信号量:empty(记录多少个空位),full(记录有多少满位)以及mutex(二进制信号量以保护对缓冲的插入与删除操作)。
buffer.h头文件声明了缓冲区数据类型,缓冲大小,以及对缓冲区可采取的操作。

/*buffer.h*/typedef int buffer_item;#define BUFFER_SIZE 5int insert_item(buffer_item);int remove_item(buffer_item *);void printBuffer();

buffer.c为缓冲区插入,删除以及打印操作的具体实现。

/*buffer.c*/#include <stdio.h>#include "buffer.h"static buffer_item buffer[BUFFER_SIZE];static int counter, in, out;int insert_item(buffer_item item) {    if (counter == BUFFER_SIZE) {        return -1;    } else {        buffer[in] = item;        in = (in + 1) % BUFFER_SIZE;        counter++;        return 0;    }}int remove_item(buffer_item *item) {    if (counter == 0) {        return -1;    } else {        *item = buffer[out];        buffer[out] = 0;        out = (out + 1) % BUFFER_SIZE;        counter--;        return 0;    }}void printBuffer() {    int k = 0;    while (k < BUFFER_SIZE) {        printf("%2d ", buffer[k++]);    }    printf("end\n");}

mutex.h头文件声明了使用的信号量。

/*mutex.h*/#include <pthread.h>#include <semaphore.h>pthread_mutex_t mutex;sem_t empty, full;

thread.h声明了生产者进程和消费者进程。

/*thread.h*/void *producer(void* param);void *consumer(void* param);

thread.c为生产者进程和消费者进程的具体实现。在临界区内对缓冲分别进行插入与移出操作,并在屏幕上显示缓冲区内容。

/*thread.c*/#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <pthread.h>#include <semaphore.h>#include "mutex.h"#include "threads.h"#include "buffer.h"void *producer(void* param) {    buffer_item item;    srand(time(NULL));    while (1) {        //before:produce an item        sleep(rand() % 5);        item = rand() % 100;        //end        //entry section        sem_wait(&empty);        pthread_mutex_lock(&mutex);        //end        //critical section        if (insert_item(item)) {            //error message            printf("producer insert item error, continue to next loop\n");            pthread_mutex_unlock(&mutex);            sem_post(&empty);            continue;        }        printf("%lu producer insert item %2d success. Current buffer is:", pthread_self(), item);        printBuffer();        //end        //exit section        pthread_mutex_unlock(&mutex);        sem_post(&full);        //end        //remainder section        //end    }}void *consumer(void* param) {    buffer_item item;    while (1) {        //before:sleep for a period of time        sleep(rand() % 5);        //end        //entry section        sem_wait(&full);        pthread_mutex_lock(&mutex);        //end        //critical section        if (remove_item(&item)) {            //error message            printf("consumer remove item error, continue to next loop\n");            pthread_mutex_unlock(&mutex);            sem_post(&full);            continue;        }        printf("%lu consumer remove item %2d success. Current buffer is:", pthread_self(), item);        printBuffer();        //end        //exit section        pthread_mutex_unlock(&mutex);        sem_post(&empty);        //end        //remainder section        //end    }}

main.c为主函数实现,内容如下:

/*main.c*/#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <pthread.h>#include <semaphore.h>#include "mutex.h"#include "threads.h"#include "buffer.h"int main(int argc, char const *argv[]){    /* code */    //1.get command line arguments argv[1], argv[2], argv[3]    if (argc < 4) {        fprintf(stderr, "need at least 3 args\n");        return -1;    }    if (atoi(argv[1]) <= 0) {        fprintf(stderr, "sleep time must be positive numbers\n");        return -1;    }    if (atoi(argv[2]) <= 0) {        fprintf(stderr, "producer threads numbers must be positive numbers\n");        return -1;    }    if (atoi(argv[3]) <= 0) {        fprintf(stderr, "consumer threads numbers must be positive numbers\n");        return -1;    }    //2.initialize    pthread_mutex_init(&mutex, NULL);    sem_init(&empty, 0, BUFFER_SIZE);    sem_init(&full, 0, 0);    //3.create producer threads    for (int i = 0; i < atoi(argv[2]); ++i)    {        pthread_t tid;        pthread_attr_t attr;        pthread_attr_init(&attr);        pthread_create(&tid, &attr, producer, NULL);    }    //4.create consumer threads    for (int i = 0; i < atoi(argv[3]); ++i)    {        pthread_t tid;        pthread_attr_t attr;        pthread_attr_init(&attr);        pthread_create(&tid, &attr, consumer, NULL);    }    //5.sleep    sleep(atoi(argv[1]));    //6.exit    exit(0);}