文章目录
概要:本期主要学习使用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;
}
结尾
本期对于生产者消费者模式的学习就到这,下期再会:)