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

    */
  • 相关阅读:
    二分+RMQ/双端队列/尺取法 HDOJ 5289 Assignment
    思维题 HDOJ 5288 OO’s Sequence
    树形DP Codeforces Round #135 (Div. 2) D. Choosing Capital for Treeland
    最大流增广路(KM算法) HDOJ 1853 Cyclic Tour
    最大流增广路(KM算法) HDOJ 1533 Going Home
    最大流增广路(KM算法) HDOJ 2255 奔小康赚大钱
    Complete the Word CodeForces
    Gadgets for dollars and pounds CodeForces
    Vasya and Basketball CodeForces
    Carries SCU
  • 原文地址:https://www.cnblogs.com/zyqy/p/10801030.html
Copyright © 2011-2022 走看看