基于单链表和环形队列的生产消费模型

来源:互联网 发布:python 自定义函数 编辑:程序博客网 时间:2024/06/05 08:55

消费者模型

消费者模型由消费者,生产者以及交易场所构成;

其中消费者与生产者的关系有以下几种:

  • 消费者—消费者:互斥
  • 消费者—生产者:互斥、同步
  • 生产者—生产者:互斥

基于单链表的消费者模型

互斥关系的由互斥锁来实现:

int pthread_mutex_lock(pthread_mutex_t *mutex);//上锁int pthread_mutex_trylock(pthread_mutex_t *mutex);int pthread_mutex_unlock(pthread_mutex_t *mutex);//解锁

以上三个函数成功返回0;

等待则由以下函数实现:

int pthread_cond_timedwait(pthread_cond_t *restrict cond,              pthread_mutex_t *restrict mutex,              const struct timespec *restrict abstime);//由time控制的等待int pthread_cond_wait(pthread_cond_t *restrict cond,              pthread_mutex_t *restrict mutex);//阻塞式等待

测试用例:
  由一个单向链表实现消费模型,建立两个线程,分别对链表进行头插,头删操作;模拟生产,消费情景:在实现互斥关系时,用互斥锁操作。最终实现:生产者生产一条数据(在链表中头插一个节点,并在屏幕上打印节点中数据),消费者跟着消费一条数据(打印链表节点中的数据)。以下是测试代码:

#include<stdio.h>#include<pthread.h>#include<stdlib.h>#include<malloc.h>pthread_mutex_t mutex_lock=PTHREAD_MUTEX_INITIALIZER;//init lockpthread_cond_t cond=PTHREAD_COND_INITIALIZER;//init cond   ypedef struct SeqList{     int data;     struct SeqList* next;}SeqList;SeqList* list=NULL;SeqList* Buynode(int d){    SeqList* list=(SeqList*)malloc(sizeof(SeqList));    list->data=d;    list->next=NULL;    return list;}void PushFront(SeqList **pplist,int d){     SeqList* tmp=Buynode(d);     tmp->next=*pplist;     *pplist=tmp;}int PopFront(SeqList** pplist){    if(*pplist==NULL)    {        return ;    }    SeqList* tmp=(*pplist)->next;    int ret=(*pplist)->data;    free(*pplist);    *pplist=tmp;    return ret; } void *product(void *arg) {     while(1) {     int d=rand()/9527;     int i=pthread_mutex_lock(&mutex_lock);//申请锁     if(i!=0)     {         pthread_cond_wait(&cond,&mutex_lock);//阻塞式等待     }     PushFront(&list,d);     printf("product %d\n",d);     pthread_mutex_unlock(&mutex_lock);//释放锁     sleep(1);     }}void *consume(void *arg){    while(1)    {        sleep(1);        int i=pthread_mutex_lock(&mutex_lock);//申请锁        int ret=PopFront(&list);        if(i!=0)        {            pthread_cond_wait(&cond,&mutex_lock);//等待        }        printf("consume %d\n",ret);        pthread_mutex_unlock(&mutex_lock);//释放锁    }}int main(){     pthread_t t_a;//定义线程     pthread_t t_b;     pthread_create(&t_a,NULL,product,(void*)NULL);//确定线程入口点     pthread_create(&t_b,NULL,consume,(void*)NULL);     pthread_join(t_b,NULL);//等待线程退出     pthread_mutex_destroy(&mutex_lock);//销毁锁     pthread_cond_destroy(&cond);//销毁条件变量     return 0;}

测试结果

这里写图片描述

基于环形队列的生产消费模型

在测试用例中先规定格子数为4,生产者先生产(打印生产好的数据),消费者每隔一秒消费一次(读取数据并打印)

这里写图片描述

实现条件

  1. 生产者不能超过消费者一圈
  2. 消费者永远跟在生产者后面

测试代码

#include<stdio.h>#include<stdlib.h>#include<pthread.h>#include<semaphore.h>#define SIZE 4int arr[SIZE]={0};int ret = 0;sem_t datasem;sem_t blanksem;void *product(void *arg){    int i=0;    while(1)    {        sem_wait(&blanksem);//有格子资源时,生产者开始生产        arr[ret]=i;        printf("product done! %d\n", arr[ret]);        sem_post(&datasem);//给消费者发出数据资源信号        i++;        ret++;        ret %= SIZE;     }}void *consume(void *arg){    while(1)    {        sem_wait(&datasem);//申请,当有数据资源时,消费者开始消费        printf("consume done! %d\n", arr[ret]);        sem_post(&blanksem);//释放,并给生产者发出格子空出信号        sleep(1);    }}int main(){    pthread_t c;//定义线程    pthread_t p;    sem_init(&datasem, 0, 0);//初始化信号量    sem_init(&blanksem,0, SIZE);    pthread_create(&p, NULL, product, NULL);//确定线程入口    pthread_create(&c, NULL, consume, NULL);    pthread_join(c, NULL);//等待线程退出    pthread_join(p, NULL);    sem_destroy(&datasem);//销毁信号量    sem_destroy(&blanksem);    return 0;}

测试结果

这里写图片描述

以上测试结果可以看出,在生产了四个数据之后,消费者开始消费,直到消费完空出格子,生产者开始生产,等着每隔一秒消费者消费后,生产者接着生产。

若有不正之处,恳请留言指正

阅读全文
0 0
原创粉丝点击