【C/C++实现生产者消费者模式】

概要:本期主要学习使用WINAPI中的信号量机制来实现生产者消费者模式。

一、WINAPI中的信号量机制

1.创建信号量在这里插入图片描述

2.释放信号量

在这里插入图片描述

3.等待信号量

在这里插入图片描述

二、生产者消费者模型

生产者消费者是一种计算机编程模型,用于解决多线程或并发编程中的同步问题。在这种模型中,生产者创建并向共享缓冲区中放置数据,而消费者则从缓冲区中取出数据并进行处理。生产者和消费者在并发执行的情况下,需要协调彼此的操作以避免竞态条件和数据不一致等问题。

生产者和消费者之间的共享缓冲区是一个数据结构,通常是一个队列或缓存区。生产者在将数据放入共享缓冲区之前必须检查其是否已满,而消费者在从中取出数据之前必须检查其是否为空。如果缓冲区已满,则生产者必须等待,直到有足够的空间可用。同样,如果缓冲区为空,则消费者必须等待,直到有数据可用。

生产者消费者模型的一个重要特点是,它可以将生产者和消费者分离开来,并允许它们以不同的速率执行。这种分离和异步执行的方式可以提高程序的效率和性能,同时保证数据的完整性和正确性。

三、代码实现

下面展示c/c++实现的代码:

#include <windows.h>
#include <iostream>
#include <queue>
#include <ctime>
#include <cstdlib>

using namespace std;

// 缓冲区大小
#define BUFFER_SIZE 10

// 生产者生产的次数
#define PRODUCER_COUNT 20

// 定义互斥量和信号量
HANDLE g_hMutex;
HANDLE g_hEmptySemaphore;
HANDLE g_hFullSemaphore;

// 缓冲区队列
queue<int> g_BufferQueue;

// 生产者线程函数
DWORD WINAPI ProducerThread(LPVOID lpParam) {
    
    
    for (int i = 0; i < PRODUCER_COUNT; ++i) {
    
    
        // 生成随机数
        int num = rand() % 100;
        // 等待空缓冲区
        WaitForSingleObject(g_hEmptySemaphore, INFINITE);
        // 获取互斥量
        WaitForSingleObject(g_hMutex, INFINITE);
        // 将数据添加到缓冲区队列中
        g_BufferQueue.push(num);
        cout << "Producer thread ID: " << GetCurrentThreadId() << " produced number: " << num << endl;
        // 释放互斥量
        ReleaseMutex(g_hMutex);
        // 发送信号表示缓冲区非空
        ReleaseSemaphore(g_hFullSemaphore, 1, NULL);
    }
    return 0;
}

// 消费者线程函数
DWORD WINAPI ConsumerThread(LPVOID lpParam) {
    
    
    while (true) {
    
    
        // 等待非空缓冲区
        WaitForSingleObject(g_hFullSemaphore, INFINITE);
        // 获取互斥量
        WaitForSingleObject(g_hMutex, INFINITE);
        // 从缓冲区队列中取出数据并打印
        int num = g_BufferQueue.front();
        g_BufferQueue.pop();
        cout << "Consumer thread ID: " << GetCurrentThreadId() << " consumed number: " << num << endl;
        // 释放互斥量
        ReleaseMutex(g_hMutex);
        // 发送信号表示缓冲区非满
        ReleaseSemaphore(g_hEmptySemaphore, 1, NULL);
        // 如果缓冲区为空,则退出循环
        if (g_BufferQueue.empty()) {
    
    
            break;
        }
    }
    return 0;
}

int main() {
    
    
    // 初始化随机数生成器
    srand(time(NULL));

    // 创建互斥量和信号量
    g_hMutex = CreateMutex(NULL, FALSE, NULL);
    g_hEmptySemaphore = CreateSemaphore(NULL, BUFFER_SIZE, BUFFER_SIZE, NULL);
    g_hFullSemaphore = CreateSemaphore(NULL, 0, BUFFER_SIZE, NULL);

    // 创建生产者和消费者线程
    HANDLE hProducerThread = CreateThread(NULL, 0, &ProducerThread, NULL, 0, NULL);
    HANDLE hConsumerThread1 = CreateThread(NULL, 0, &ConsumerThread, NULL, 0, NULL);
    HANDLE hConsumerThread2 = CreateThread(NULL, 0, &ConsumerThread, NULL, 0, NULL);

    // 等待线程执行完毕
    WaitForSingleObject(hProducerThread, INFINITE);
    WaitForSingleObject(hConsumerThread1, INFINITE);
   
   //清除WINAPI句柄
   CloseHandle(g_hMutex);
   CloseHandle(g_hEmptySemaphore );
   CloseHandle(g_hFullSemaphore );
   
   return 0;
}

结尾

本期对于生产者消费者模式的学习就到这,下期再会:)

猜你喜欢

转载自blog.csdn.net/wddkxg/article/details/129828277