zoukankan      html  css  js  c++  java
  • 信号量生产者和消费者模型

    使用信号量完成线程间同步,模拟生产者,消费者问题。                                         【sem_product_consumer.c】

    思路分析:

      规定: 如果□中有数据,生产者不能生产,只能阻塞。

      如果□中没有数据,消费者不能消费,只能等待数据。

      定义两个信号量:S满 = 0, S空 = 1 (S满代表满格的信号量,S空表示空格的信号量,程序起始,格子一定为空) 

    -------------------------------------------------------------------------------------------------------------------------------------

      所以有:T生产者主函数 {           T消费者主函数 {

            sem_wait(S空);             sem_wait(S满);

            生产....                 消费....

            sem_post(S满);             sem_post(S空);

            }                }

    -------------------------------------------------------------------------------------------------------------------------------------

    假设:线程到达的顺序是:T生、T生、T消。

    那么: T生1 到达,将S空-1,生产,将S满+1

       T生2 到达,S空已经为0, 阻塞

       T消 到达,将S满-1,消费,将S空+1

    三个线程到达的顺序是:T生1、T生2、T消。而执行的顺序是T生1、T消、T生2

    这里,S空 表示空格子的总数,代表可占用信号量的线程总数-->1。其实这样的话,信号量就等同于互斥锁。

    但,如果S空=2、3、4……就不一样了,该信号量同时可以由多个线程占用,不再是互斥的形式。因此我们说信号量是互斥锁的加强版。

    //信号量实现 生产者 消费者问题
    
    #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()%1);
        }
    
    }
    
    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;
    }
    /*
    输出:

    ------Produce------384
    ------Consume------384
    ------Produce------916
    ------Produce------336
    ------Produce------493
    ------Produce------422
    ------Produce------28
    ------Consume------916
    ------Produce------764
    ------Consume------336
    ------Produce------427
    ------Consume------493
    ------Produce------212
    ------Consume------422
    ------Produce------430
    ------Consume------28
    ------Produce------863
    ------Consume------764
    ------Produce------136
    ------Consume------427
    ------Consume------212
    ------Produce------59
    ------Consume------430
    ------Consume------863
    ------Produce------457
    ------Produce------43
    ------Produce------374
    ------Consume------136
    ------Produce------785
    ------Consume------59
    ------Produce------325
    ------Consume------457
    ------Produce------414
    ------Consume------43
    ------Produce------981

    */
  • 相关阅读:
    选择屏幕工具栏按钮
    通过TCODE查找SPRO路径
    程序间获取ALV显示数据(读取ALV GRID上的数据)
    CL_GUI_FRONTEND_SERVICES 使用问题
    OO ALV 后台运行时错误:Control Framework: Fatal error
    SAP EXCEL OLE常用方法和属性
    OCR论文整理
    pytorch文档阅读(一)
    目标检测论文整理
    PHP excel 科学计数法 画格子线
  • 原文地址:https://www.cnblogs.com/zyqy/p/10801030.html
Copyright © 2011-2022 走看看