Linux系统编程:使用semaphore信号量和mutex互斥量实现多个生产者和消费者模型

时间:2022-08-18 17:38:43

代码实现

如题,使用semaphore信号量和mutex互斥量实现多个生产者和消费者模型。本来是想只用信号量实现生产者消费者模型的,但是发现 只能在一个生产者和一个消费者之间,要在多个生产者和消费者模型必须和mutex互斥锁搭配使用才行,sem信号量只是控制并发数的。采用数组模拟产品区,代码中有一定的注释。需要Linux下线程相关知识进行支撑,这里不细说,直接看实现代码。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <error.h>
#include <sys/errno.h>
#include <pthread.h>
#include <semaphore.h>
#define NUM 10 //产品区容量
int queue[NUM] = {0};//数组模拟产品区,生产者消费者运行模拟环形队列进行生产和消费
sem_t producer,customer;//信号量
int pro_i = 0;//生产者线程 访问下标
int cus_i = 0;//消费者线程 访问下标
pthread_mutex_t pro_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t cus_lock = PTHREAD_MUTEX_INITIALIZER;

//生产者
void* produce(void* arg)
{
    int tmp;
    //生产从下标 0 -> N
    while(1)
    {
        sem_wait(&producer); //producer-- ,直到为0 产品区被填满 进行阻塞

        //并行的生产者线程生成产品
        pthread_mutex_lock(&pro_lock);  
        tmp = queue[pro_i] = rand()%1000 ;
        pro_i = (pro_i+1)%NUM;
        pthread_mutex_unlock(&pro_lock);
        
        printf("%dth ###producer###:%d\n",(int)arg,tmp);
        sem_post(&customer);//customer++
        sleep(rand()%2);
    }
    return NULL;
}
//消费者
void* custome(void* arg)
{
    int tmp;
    //消费从下标0 -> N 
    while(1)
    {
        sem_wait(&customer); // customer-- ,直到为0 产品区为空 进行阻塞

        //并行的消费者线程访问消费产品
        pthread_mutex_lock(&cus_lock);
        tmp = queue[cus_i];
        queue[cus_i] = 0 ;
        cus_i = (cus_i+1)%NUM;
        pthread_mutex_unlock(&cus_lock);

        printf("%dth ***customer***:%d\n",(int)arg,tmp);
        sem_post(&producer);//producer++ 
        sleep(rand()%2);
    }
    return NULL;
}
//使用信号量 实现生产者消费者模型
int main(int argc,char* argv[])
{
    srand((unsigned int)time(NULL));
    //设置线程分离
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
    pthread_t pro[3],cus[5]; 
    int i;
    //初始化信号量 起初产品区为空
    sem_init(&producer,0,NUM);//生产者 起初信号量为 NUM 产品区为空生产产品,当信号量为0 也就是产品满 阻塞等待消费者消费产品
    sem_init(&customer,0,0);  //消费者 起初信号量为 0 阻塞等待生产者生产产品
    for( i= 0; i< 3;i++ )
    {
        pthread_create(&pro[i],&attr,produce,(void*)i);
    }
    for( i= 0; i< 5;i++ )
    {
        pthread_create(&cus[i],&attr,custome,(void*)i);
    }
    //销毁 信号量
    sem_destroy(&producer);
    sem_destroy(&customer);
    //销毁 锁
    pthread_mutex_destroy(&pro_lock);
    pthread_mutex_destroy(&cus_lock);
    //主线程退出
    pthread_exit(NULL);
    return 0;
}


实现效果

Linux系统编程:使用semaphore信号量和mutex互斥量实现多个生产者和消费者模型