线程之生产者——消费者问题(条件变量)

生产者——消费者问题(producers and consumers,problem)

/*伪代码*/
#define BUFFER_SIZE k
itemType buffer[BUFFER_SIZE];//全局数组作为线程间共享的数据
int in=0;//in为放入指针
int out=0;//out为取出指针
int count=0;count为缓冲区已放入指针计数量
semaphore mutex=1;//静态创建锁或全局变量动态锁
pthread_cond_t p_cond=PTHREAD_COND_INITIALIZER;//条件变量初始化为PTHREAD_COND_INITIALIZER;
/*生产者伪代码*/
void producer(){
	while(1){
		produceItem(&item);
		P(s1);
		P(mutex);
		buffer[in]=item;
		in=(in+1)%BUFFER_SIZE;
		V(mutex);
		V(s2);
	}
}
/*消费者伪代码*/
void consumer(){
	itemType x;
	while(1){
		P(s2);
		P(mutex);
		x=buffer[out];
		out=(out+1)%BUFFER_SIZE;
		V(mutex);
		V(s1);
		consumeItem(x);
	}
}
/*用pthread线程+condition variables+mutex模拟第3题的“生产者-消费者”问题*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>//信号量sem_t函数头文件
#include "buffer.h"  //缓冲区头文件

buffer_item buffer[BUFFER_SIZE];//全局数组作为线程间共享的数据
int in_pthread=0,out_pthread=0;//in_pthread为放入指针,out_pthread为取出指针
int count_pthread=0;//counr_pthread为缓冲区已放入指针计数量
pthread_mutex_t p_lock;//全局变量动态锁
pthread_cond_t p_cond;//条件变量

void *producer(void *param);//生产者线程
void *consumer(void *param);//消费者线程
int insert_item(buffer_item item);//生产者插入
int remove_item(buffer_item *item);//消费者取出

int main(int argc,char *argv[])
{
    /*判断参数的合法性*/
    if(argc<4)
    {
        printf("lack of parameters\n");
        exit(0);
    }
    int n=atoi(argv[1]);
    if(n<0)
    {
        printf("Wrong input of sleep time!\n");
        exit(0);
    }
    if(atoi(argv[2])<0)
    {
        printf("Wrong input of producer threads numbers!\n");
        exit(0);
    }
    if(atoi(argv[3])<0)
    {
        printf("Wrong input of consumer threads numbers!\n");
        exit(0);
    }
    /*创建锁及条件变量初值*/
    pthread_mutex_init(&p_lock,NULL);//动态创建锁
    pthread_cond_init(&p_cond,NULL);//条件变量初始化
    /*创建生产者线程*/
    int i;
    for(i=1;i<=atoi(argv[2]);i++)
    {
        pthread_t tid_producer;
        pthread_attr_t attr;//const pthread_attr_t *attr的分离属性
        pthread_attr_init(&attr);
        pthread_create(&tid_producer,&attr,producer,(void *)i);
    }
    /*创建消费者线程*/
    for(i=1;i<=atoi(argv[3]);i++)
    {
        pthread_t tid_consumer;
        pthread_attr_t attr;
        pthread_attr_init(&attr);
        pthread_create(&tid_consumer,&attr,consumer,(void *)i);
    }

    pthread_mutex_destroy(&p_lock);//删除动态锁
    /*sleep等待n秒*/
    sleep(n);

    return 0;
}
void *producer(void *param)
{
	buffer_item item;
	srand((unsigned)time(NULL));
	while(1)
    {
        sleep(rand()%5+1);//睡1~5范围内的随机秒数
        item=rand()%5+1;//生成1~5范围内的随机整数
        if(insert_item(item))
            printf("Produce error\n");//打印“出错信息”
        else
            printf("Producer thread %d produce %d\n",param,item);//打印“生产者线程param生产了item”
    }
    pthread_exit(0);
}
void *consumer(void *param)
{
	buffer_item item;
	srand((unsigned)time(NULL));
	while(1)
    {
        sleep(rand()%5+1);//睡1~5范围内的随机秒数
        if(remove_item(&item))
            printf("Remove error\n");//打印“出错信息”
        else
            printf("Consumer thread %d consume %d\n",param,item);//打印“消费者线程param消费了item”
    }
    pthread_exit(0);
}
int insert_item(buffer_item item)//insert item into buffer
{
    if(count_pthread==BUFFER_SIZE)
        return -1;
    else
    {
        pthread_mutex_lock(&p_lock);//上锁
        while((in_pthread+1)%BUFFER_SIZE==out_pthread || count_pthread==BUFFER_SIZE)//缓冲区为满时等待
        {
            pthread_cond_wait(&p_cond,&p_lock);//等待缓冲区非空,wait的同时会原子释放锁
        }
        buffer[in_pthread]=item;
        in_pthread=(in_pthread+1)%BUFFER_SIZE;
        count_pthread++;
        //printf("P---> %d\n",count_pthread);////测试count_pthread的值
        pthread_mutex_unlock(&p_lock);//解锁
    }
	return 0;

}
int remove_item(buffer_item *item)//remove item from buffer
{//使用*item是为了从buffer中取数
    if(count_pthread==0)
        return -1;
    else
    {
        pthread_mutex_lock(&p_lock);//上锁
        *item=buffer[out_pthread];
        buffer[out_pthread]=0;
        out_pthread=(out_pthread+1)%BUFFER_SIZE;
        count_pthread--;
        //printf("C<--- %d,item=%d\n",count_pthread,*item);//测试count_pthread的值
        if(in_pthread==out_pthread)
            pthread_cond_signal(&p_cond);//被唤醒,重新获得锁并返回
        pthread_mutex_unlock(&p_lock);//解锁
    }
	return 0;
}

友情链接:
(1)生产者和消费者问题
https://wenku.baidu.com/view/e8a53ff32b160b4e777fcfbc.html

(2)互斥锁和条件变量实现生产者消费者问题
http://www.cnblogs.com/XNQC1314/p/9178120.html

(3)生产者消费者模型(Linux系统下的两种实现方法)
https://blog.csdn.net/yusiguyuan/article/details/48265205

(4)线程-条件变量(实现生产者和消费者问题)
https://blog.csdn.net/qq_38635597/article/details/80045817

(5)条件变量
https://www.cnblogs.com/ACGame/p/9102241.html

(6)深入解析条件变量(condition variables)
https://www.cnblogs.com/harlanc/p/8596211.html

意外发现:
(1)生产者消费者问题的pthread模拟
https://blog.csdn.net/sinat_16709955/article/details/75208019

猜你喜欢

转载自blog.csdn.net/JxufeCarol/article/details/89389317