单进程:信号量+互斥锁,实现[多生产者/多消费者]模型

单进程:信号量+互斥锁,实现[多生产者/多消费者]模型


// 编译方式: gcc main.c -o main -lpthread

/**
*@author    guojawee
*@date      2012/05/21
*@detail    单进程:信号量+互斥锁,实现[多生产者/多消费者]模型
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

#include <semaphore.h>

#define BUFFSIZE 9 // 缓冲池大小 

struct queue_type     //缓冲池队列 
{
	int buff[BUFFSIZE];
	int front;	//队头,消费者从对头取出"产品” 
	int rear;	//队尾,生产者从队尾放入"产品“ 
}Q={{0},0,0};		

sem_t empty; // 生产者私有信号量,表示空缓冲区数目 。 
sem_t full;   //消费者私有变量,表示有产品的缓冲区数目。 
pthread_mutex_t mutex; // 公有信号量,用于实现对临界区互斥访问 

int producer_id = 0;   //生产者编号,初值为0 
int consumer_id = 0;   //消费者编号,初值为0 

/* 打印缓冲池情况*/
void print()
{
     int i;
     for(i = 0; i < BUFFSIZE; i++)
     printf("%d ", Q.buff[i]);
     printf("\n");
}

/*生产者*/
void *producer()
{
     int id=++producer_id;

     while(1)
      {
             sleep(1);	//		
  
             sem_wait(&empty);	//申请空缓冲区 
             pthread_mutex_lock(&mutex);	//申请队列互斥 

             Q.buff[Q.rear] = 1;   //将产品放入rear所指向的缓冲区 
             printf("producer number<%d> thread idetifier:%u put into buffer[%d].The buffer is like: \t", id, ((unsigned int)pthread_self()),Q.rear+1);
             print();  
             Q.rear = (Q.rear+1) % BUFFSIZE;
  
             pthread_mutex_unlock(&mutex);	//释放队列互斥 
             sem_post(&full);  	//释放满缓冲区 
      }
}

/* 消费者*/
void *consumer()
{
     int id=++consumer_id;
     while(1)
      {
             sleep(1);

             sem_wait(&full);  //申请满缓冲区 
             pthread_mutex_lock(&mutex);     //申请队列互斥 
   
             Q.buff[Q.front] = 0;            //从front所指向的缓冲区取产品 
             printf("consumer number<%d> thread idetifier:%u get from buffer[%d].The buffer is like: \t", id,((unsigned int)pthread_self()), Q.front+1);
             print();
             Q.front = (Q.front+1) % BUFFSIZE;
  
             pthread_mutex_unlock(&mutex);    //释放队列互斥 
             sem_post(&empty);                //释放空缓冲区 
      }
}

int main()
{
    int M,N;  //M为生产者者数目,N为消费者数目 
    printf("please input the producers number: ");
    scanf("%d",&M);
    printf("please input the consumers number: ");
    scanf("%d",&N);
    pthread_t id1[M];		//存储生产者线程ID 
    pthread_t id2[N];		//存储消费者者线程ID 
    int i;
    int ret1[M],ret2[N];  //存储创建生产者和消费者线程的返回值。 


/*初始化empty和full私有信号量 */
    int ini1 = sem_init(&empty, 0, BUFFSIZE);//初始化empty信号量,大小为Buffersize ,初始化成功返回零,失败返回-1  
    int ini2 = sem_init(&full, 0, 0);        //初始化full信号量,大小为0                                 
    if((ini1 || ini2)!=0)	//
    {
             printf("sem init failed \n");
             exit(1);
    }

/*初始化公有信号量 mutex*/
    int ini3 = pthread_mutex_init(&mutex, NULL);	//以默认方式创建互斥锁(快速互斥锁) ,初始化为未锁状态,成功返回0 
    if(ini3 != 0)
    {
            printf("mutex init failed \n");
            exit(1);
    }
    
/*创建生产者线程*/
    for(i = 0; i < M; i++)
    {
            ret1[i] = pthread_create(&id1[i], NULL, producer, (void *)(&i));	//循环创建生产者线程,成功返回0 
            if(ret1[i] != 0)
            {
               printf("producer%d creation failed \n", i);
               exit(1);
            }
    }
    
/*创建消费者线程*/ 
    for(i = 0; i < N; i++)
    {
            ret2[i] = pthread_create(&id2[i], NULL, consumer, NULL);         //循环创建消费者线程,成功返回0 
            if(ret2[i] != 0)
            {
               printf("consumer%d creation failed \n", i);
               exit(1);
            }
    }
    
/*销毁线程*/
    for(i = 0; i < M; i++)
    {
            pthread_join(id1[i],NULL);   //对创建的生产者线程进行资源回收 
    }
    for(i = 0; i < N; i++)
    { 
            pthread_join(id2[i],NULL);   //对创建的消费者线程进行资源回收 
    }

    exit(0);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值