📜  生产者消费者问题及其C++实现

📅  最后修改于: 2021-09-27 22:53:31             🧑  作者: Mango

概述 :
在本文中,我们将讨论生产者-消费者问题及其使用 C++ 的实现。生产者-消费者问题是一个经典的两进程同步问题。让我们一一讨论。

问题陈述 :
在生产者-消费者问题中有一个生产者和一个消费者。

  1. 制作人——
    生产者进程执行一组语句 intproduce 来创建一个数据元素并将其存储在缓冲区中。
  2. 消费者 –
    如果缓冲区有项目,消费者进程将执行一条语句,以数据元素作为参数。

解决方案 :
问题出现的原因是流程不同步,因此生产和消费的项目可能不一致。为了解决这个问题,我们使用信号量来解决这个问题,即临界区问题。

在 C++ 中的实现:
这个问题可以进一步细分为如下两部分。

第 1 部分:缓冲区大小是无限的——
在这种情况下,生产者存储项目和消费者消费项目的缓冲区大小不固定。

C++14
#include
#include
#include
#include  
using namespace std;
  
// Declaration
int r1,total_produced=0,total_consume=0;
  
// Semaphore declaration
sem_t notEmpty;
  
// Producer Section
void* produce(void *arg){
    while(1){
      cout<<"Producer produces item."<


C++14
#include 
#include 
#include 
#include 
using namespace std;
  
// Declaration
int r1, items = 0;
  
// Semaphore declaration
sem_t notEmpty, notFull;
  
// Producer Section
void* produce(void* arg)
{
    while (1) {
        sem_wait(¬Full);
        sleep(rand() % 100 * 0.01);
        cout << 
      "Producer produces item.Items Present = "
             << ++items << endl;
        sem_post(¬Empty);
        sleep(rand() % 100 * 0.01);
    }
}
  
// Consumer Section
void* consume(void* arg)
{
    while (1) {
        sem_wait(¬Empty);
        sleep(rand() % 100 * 0.01);
        cout << 
     "Consumer consumes item.Items Present = "
             << --items << endl;
        sem_post(¬Full);
        sleep(rand() % 100 * 0.01);
    }
}
  
int main(int argv, char* argc[])
{
  
    int N;
    cout << 
      "Enter the capacity of the buffer" << endl;
    cin >> N;
  
    // thread declaration
    pthread_t producer, consumer;
  
    // Declaration of attribute......
    pthread_attr_t attr;
  
    // semaphore initialization
    sem_init(¬Empty, 0, 0);
    sem_init(¬Full, 0, N);
  
    // pthread_attr_t initialization
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr,
             PTHREAD_CREATE_JOINABLE);
  
    // Creation of process
    r1 = pthread_create(&producer, &attr, 
                        produce, NULL);
    if (r1) {
        cout << 
          "Error in creating thread" << endl;
        exit(-1);
    }
  
    r1 = pthread_create(&consumer, &attr, 
                        consume, NULL);
    if (r1) {
        cout << 
          "Error in creating thread" << endl;
        exit(-1);
    }
  
    // destroying the pthread_attr
    pthread_attr_destroy(&attr);
  
    // Joining the thread
    r1 = pthread_join(producer, NULL);
    if (r1) {
        cout << "Error in joining thread" << endl;
        exit(-1);
    }
  
    r1 = pthread_join(consumer, NULL);
    if (r1) {
        cout << "Error in joining thread" << endl;
        exit(-1);
    }
  
    // Exiting thread
    pthread_exit(NULL);
  
    return 0;
}


第 2 部分:缓冲区大小固定或有限的地方 –
在这种情况下,生产者存储项目和消费者消费项目的缓冲区大小是固定的。

C++14

#include 
#include 
#include 
#include 
using namespace std;
  
// Declaration
int r1, items = 0;
  
// Semaphore declaration
sem_t notEmpty, notFull;
  
// Producer Section
void* produce(void* arg)
{
    while (1) {
        sem_wait(¬Full);
        sleep(rand() % 100 * 0.01);
        cout << 
      "Producer produces item.Items Present = "
             << ++items << endl;
        sem_post(¬Empty);
        sleep(rand() % 100 * 0.01);
    }
}
  
// Consumer Section
void* consume(void* arg)
{
    while (1) {
        sem_wait(¬Empty);
        sleep(rand() % 100 * 0.01);
        cout << 
     "Consumer consumes item.Items Present = "
             << --items << endl;
        sem_post(¬Full);
        sleep(rand() % 100 * 0.01);
    }
}
  
int main(int argv, char* argc[])
{
  
    int N;
    cout << 
      "Enter the capacity of the buffer" << endl;
    cin >> N;
  
    // thread declaration
    pthread_t producer, consumer;
  
    // Declaration of attribute......
    pthread_attr_t attr;
  
    // semaphore initialization
    sem_init(¬Empty, 0, 0);
    sem_init(¬Full, 0, N);
  
    // pthread_attr_t initialization
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr,
             PTHREAD_CREATE_JOINABLE);
  
    // Creation of process
    r1 = pthread_create(&producer, &attr, 
                        produce, NULL);
    if (r1) {
        cout << 
          "Error in creating thread" << endl;
        exit(-1);
    }
  
    r1 = pthread_create(&consumer, &attr, 
                        consume, NULL);
    if (r1) {
        cout << 
          "Error in creating thread" << endl;
        exit(-1);
    }
  
    // destroying the pthread_attr
    pthread_attr_destroy(&attr);
  
    // Joining the thread
    r1 = pthread_join(producer, NULL);
    if (r1) {
        cout << "Error in joining thread" << endl;
        exit(-1);
    }
  
    r1 = pthread_join(consumer, NULL);
    if (r1) {
        cout << "Error in joining thread" << endl;
        exit(-1);
    }
  
    // Exiting thread
    pthread_exit(NULL);
  
    return 0;
}