zoukankan      html  css  js  c++  java
  • 生产者-消费者模型

    1. 条件变量+互斥锁 实现 生产者-消费者模型:

    /*借助条件变量模拟 生产者-消费者 问题*/
    #include <stdlib.h>
    #include <unistd.h>
    #include <pthread.h>
    #include <stdio.h>
    
    /*链表作为公享数据,需被互斥量保护*/    //模拟箩筐
    struct msg {
        struct msg *next;
        int num;
    };
    
    struct msg *head;
    struct msg *mp;
    
    /* 静态初始化 一个条件变量 和 一个互斥量*/
    pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;    //条件变量静态初始化
    pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;        //互斥锁静态初始化
    
    void *consumer(void *p)//消费者
    {
        for (;;) {
            pthread_mutex_lock(&lock);//加锁
            while (head == NULL) {           //头指针为空,说明没有节点    可以为if吗
                pthread_cond_wait(&has_product, &lock);
            }
            mp = head;      
            head = mp->next;    //模拟消费掉一个产品
            pthread_mutex_unlock(&lock);//解锁
    
            printf("-Consume ---%d
    ", mp->num);
            free(mp);
            mp = NULL;
            sleep(rand() % 5);
        }
    }
    
    void *producer(void *p)//生产者
    {
        for (;;) {
            mp = malloc(sizeof(struct msg));
            mp->num = rand() % 1000 + 1;        //模拟生产一个产品
            printf("-Produce ---%d
    ", mp->num);
    
            pthread_mutex_lock(&lock);//加锁
            mp->next = head;//头插法
            head = mp;
            pthread_mutex_unlock(&lock);//解锁
    
            pthread_cond_signal(&has_product);  //将等待在该条件变量上的一个线程唤醒
            sleep(rand() % 5);
        }
    }
    
    int main(int argc, char *argv[])
    {
        pthread_t pid, cid;
        srand(time(NULL));
    
        pthread_create(&pid, NULL, producer, NULL);//创建生产者线程
        pthread_create(&cid, NULL, consumer, NULL);//创建消费者线程
    
        pthread_join(pid, NULL);//回收线程
        pthread_join(cid, NULL);
    
        return 0;
    }

    2. 信号量 实现 生产者-消费者模型:

     

    /*信号量实现 生产者 消费者问题*/
    
    #include <stdlib.h>
    #include <unistd.h>
    #include <pthread.h>
    #include <stdio.h>
    #include <semaphore.h>
    
    #define NUM 5               
    
    int queue[NUM];                                     //全局数组实现环形队列
    sem_t blank_number, product_number;                 //空格子信号量, 产品信号量
    
    void *producer(void *arg)
    {
        int i = 0;
    
        while (1) {
            sem_wait(&blank_number);                    //生产者将空格子数--,为0则阻塞等待
            queue[i] = rand() % 1000 + 1;               //生产一个产品,存入队列
            printf("----Produce---%d
    ", queue[i]);        
            sem_post(&product_number);                  //将产品数++
    
            i = (i+1) % NUM;                            //借助下标实现环形,下标往后移
            sleep(rand()%3);
        }
    }
    
    void *consumer(void *arg)
    {
        int i = 0;
    
        while (1) {
            sem_wait(&product_number);                  //消费者将产品数--,为0则阻塞等待
            printf("-Consume---%d
    ", queue[i]);
            queue[i] = 0;                               //消费一个产品 
            sem_post(&blank_number);                    //消费掉以后,将空格子数++
    
            i = (i+1) % NUM;
            sleep(rand()%3);
        }
    }
    
    int main(int argc, char *argv[])
    {
        pthread_t pid, cid;
    
        sem_init(&blank_number, 0, NUM);                //初始化空格子信号量为5
        sem_init(&product_number, 0, 0);                //产品数为0
    
        pthread_create(&pid, NULL, producer, NULL);    //创建生产者线程
        pthread_create(&cid, NULL, consumer, NULL);    //创建消费者线程
    
        pthread_join(pid, NULL);    //回收线程
        pthread_join(cid, NULL);
    
        sem_destroy(&blank_number);    //销毁信号量
        sem_destroy(&product_number);
    
        return 0;
    }
  • 相关阅读:
    UVA1349 Optimal Bus Route Design 最优巴士路线设计
    POJ3565 Ants 蚂蚁(NEERC 2008)
    UVA1663 Purifying Machine 净化器
    UVa11996 Jewel Magic 魔法珠宝
    NEERC2003 Jurassic Remains 侏罗纪
    UVA11895 Honorary Tickets
    gdb调试coredump(使用篇)
    使用 MegaCLI 检测磁盘状态并更换磁盘
    员工直接坦诚直来直去 真性情
    山东浪潮超越3B4000申泰RM5120-L
  • 原文地址:https://www.cnblogs.com/si-lei/p/9653006.html
Copyright © 2011-2022 走看看