• 生产者-消费者模型


    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;
    }
  • 相关阅读:
    expect脚本实例
    Linux dialog详解(图形化shell)
    makefile——小试牛刀
    gdb入门
    linux常见系统调用函数列表
    linux前后台任务的切换以及执行暂停
    centos 7.0 lnmp安装部署步骤
    环境列表
    setjmp与longjmp非局部跳转函数的使用
    malloc,calloc,alloca和free函数
  • 原文地址:https://www.cnblogs.com/si-lei/p/9653006.html
Copyright © 2020-2023  润新知