使用条件变量实现生产者-消费者问题,其中存在2个生产者和1个消费者
- 使用cond控制消费者从仓库拿取物品
- 使用mutex控制仓库中物品数量一次只有一个线程进行修改
- 仓库使用队列存储,先生成的物品被先取出
#include <func.h>
typedef struct Node_t{
int val;
struct Node_t *next;
}Node;
typedef struct listNode_t{
int size;
Node* front;
Node* tail;
}listNode;
typedef struct Pro_Cus
{
listNode* que;
pthread_mutex_t mutex;
pthread_cond_t cond;
}pro_cus_t;
void producter1(void* arg)
{
pro_cus_t* p = (pro_cus_t*)arg;
while(1)
{
//生产一个产品
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->val = rand() % 100 + 1;
newNode->next = NULL;
printf("> produce1: %d\n", newNode->val);
//准备将产品放入仓库
pthread_mutex_lock(&p->mutex);
if(p->que->size == 0){
p->que->front = p->que->tail = newNode;
p->que->size = 1;
}
else{
p->que->tail->next = newNode;
p->que->tail = newNode;
p->que->size++;
}
pthread_mutex_unlock(&p->mutex);
//通知消费者取产品
pthread_cond_signal(&p->cond);
sleep(rand() % 5);
}
}
void producter2(void* arg)
{
pro_cus_t* p = (pro_cus_t*)arg;
while(1)
{
//生产一个产品
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->val = rand() % 100 + 1;
newNode->next = NULL;
printf("> produce2: %d\n", newNode->val);
//准备将产品放入仓库
pthread_mutex_lock(&p->mutex);
if(p->que->size == 0){
p->que->front = p->que->tail = newNode;
p->que->size = 1;
}
else{
p->que->tail->next = newNode;
p->que->tail = newNode;
p->que->size++;
}
pthread_mutex_unlock(&p->mutex);
//通知消费者取产品
pthread_cond_signal(&p->cond);
sleep(rand() % 5);
}
}
void consumer(void* arg)
{
pro_cus_t* q = (pro_cus_t*)arg;
while(1)
{
pthread_mutex_lock(&q->mutex);
Node* delNode;
while(q->que->size == 0)
{
//没得产品,等生产者生产
pthread_cond_wait(&q->cond,&q->mutex);
}
//取到产品
delNode = q->que->front;
printf(">> consumer: %d\n", delNode->val);
q->que->front = q->que->front->next;
q->que->size--;
free(delNode);
pthread_mutex_unlock(&q->mutex);
sleep(rand() % 5);
}
}
int main(int argc, char* argv[])
{
srand(time(NULL));
pro_cus_t resource;
resource.que = (listNode*)malloc(sizeof(listNode));
resource.que->size = 0;
resource.que->front = resource.que->tail = (Node*)malloc(sizeof(Node));
pthread_mutex_init(&resource.mutex, NULL);
pthread_cond_init(&resource.cond, NULL);
pthread_t pid[2], cid;
int ret;
ret = pthread_create(&pid[0], NULL, (void*)producter1, (void*)&resource);
THREAD_ERR_CHECK(ret,"pthread_create1");
ret = pthread_create(&pid[1], NULL, (void*)producter2, (void*)&resource);
THREAD_ERR_CHECK(ret, "pthread_create2");
ret = pthread_create(&cid, NULL, (void*)consumer, (void*)&resource);
THREAD_ERR_CHECK(ret, "pthread_create_cus");
pthread_join(pid[0], NULL);
pthread_join(pid[1], NULL);
pthread_join(cid, NULL);
pthread_mutex_destroy(&resource.mutex);
pthread_cond_destroy(&resource.cond);
return 0;
}
效果如下: