生产者消费者模型

该文章介绍了如何利用线程控制机制Mutex和Cond实现生产者消费者模型。在该模型中,生产者在仓库非满时添加任务,消费者在仓库非空时获取任务。代码示例展示了如何创建自定义数据结构(环形队列)作为任务容器,并创建生产者和消费者线程进行交互。生产者投递5次任务后停止,消费者则持续获取并执行任务,每个任务运行时间为2s。
摘要由CSDN通过智能技术生成

生产者消费者模型

生产者消费者模型是经典的线程控制与任务传递案例

  • 生产者工作条件:仓库非满,添加任务.如果添加任务成功则成功唤醒一个消费者
  • 挂起条件:仓库为满,等待唤醒.
  • 消费者工作条件:仓库非空,获取任务.获取任务成功则唤醒一个生产者
  • 挂起条件:仓库为空,等待唤醒
生产者消费者模型设计分析:
  • 任务类别 :消息包,协议包,模块功能
  • 任务容器类别 :自定义数据结构(环形队列)
  • 确定线程身份:生产者消费者
  • 确认生产者消费者的工作条件与挂起条件
使用Mutex、Cond、Pthread实现生产者消费者模型,并进行测试:
  • 1生成者线程,10消费者线程
  • 任务为功能模块,任务运行时间为2s
  • 生产者投递5次任务即可
  • 消费者线程持续获取任务(while循环)
代码
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

pthread_mutex_t lock;
pthread_cond_t not_full;
pthread_cond_t not_empty;

typedef struct
{
		void *(*tjobs)(void*);
		void * arg;
}task_t;

typedef struct
{
		int front;
		int rear;
		int max;
		int cur;
		task_t * task_queue;
}queue_t;

int pthread_add_task(queue_t *,task_t);
queue_t *pthreadd_container_create(int);
int pthread_containner_destroy(queue_t *);

queue_t *pthread_container_create(int max)
{
		queue_t *p;
		if((p = (queue_t *)malloc(sizeof(queue_t)))==NULL){
				perror("malloc queue call failed");
				exit(0);
		}
		p->front = 0;
		p->rear = 0;
		p->max = max;
		p->cur = 0;

		if((p->task_queue = (task_t *)malloc(sizeof(task_t) * max)) == NULL)
		{
				perror("malloc task_queue call failed");
				exit(0);
		}
		if(pthread_mutex_init(&lock,NULL) != 0 || pthread_cond_init(&not_full,NULL)!=0 || pthread_cond_init(&not_empty,NULL) != 0){
				printf("init lock or connd error\n");
				exit(0);
		}
		return p;
}

int pthread_container_destory(queue_t *p)
{
		free(p->task_queue);
		pthread_mutex_destroy(&lock);
		pthread_cond_destroy(&not_full);
		pthread_cond_destroy(&not_empty);
		free(p);
		return 0;
}

int pthread_add_task(queue_t *p,task_t task)
{
		pthread_mutex_lock(&lock);
		while(p->max == p->cur)
				pthread_cond_wait(&not_full,&lock);

		p->task_queue[p->front].tjobs = task.tjobs;
		p->task_queue[p->front].arg = task.arg;
		++(p->cur);
		p->front = (p->front +1)%p->max;
		pthread_mutex_unlock(&lock);
		pthread_cond_signal(&not_empty);
		return 0;
}

void * pthread_customer_job(void * arg)
{
		task_t task;
		queue_t *p = (queue_t *)arg;
		while(1){
				pthread_mutex_lock(&lock);
				while(p->cur ==0)
						pthread_cond_wait(&not_empty,&lock);

				task.tjobs = p->task_queue[p->rear].tjobs;
				task.arg = p->task_queue[p->rear].arg;
				--(p->cur);
				p->rear = (p->rear+1)% p->max;
				pthread_mutex_unlock(&lock);
				pthread_cond_signal(&not_full);
				task.tjobs(task.arg);
		}
		pthread_exit(NULL);
}


void * userjobs(void * arg)
{
		printf("customer thread tid %x running \n",(unsigned int)pthread_self());
		printf("................................\n");
		sleep(2);
		return NULL;
}


int main()
{
		queue_t *p = pthread_container_create(100);

		pthread_t tids[10];
		for(int i=0;i<10;i++)
				pthread_create(&tids[i],NULL,pthread_customer_job,(void*)p);

		task_t task;
		task.tjobs = userjobs;
		task.arg = NULL;
		for(int i=0;i<5;i++)
				pthread_add_task(p,task);

		while(1)
				sleep(1);
		return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值