一个线程向队列中的队列头部读取数据,一个线程向队列中的队列尾部写入数据
首先需要分析,这两个线程之间有哪些同步信息和互斥变量
1. 当队列为空时,读取数据线程必须等待写入数据向队列中写入数据。也就是说当队列为空时,读取数据线程要等待队列中有数据。
2. 当队列满时,写入数据线程必须等待读取数据线程向队列中读取数据。也就是说当队列满时,写入数据线程要等待队列中有空位。
#include <stdio.h>
#include <process.h>
#include <windows.h>
#include <time.h>
const int QUEUE_LEN = 3;
int g_arrDataQueue[QUEUE_LEN];
int g_i, g_j, g_nDataNum;
//关键段 用于保证互斥的在屏幕上输出
CRITICAL_SECTION g_cs;
//信号量 g_hEmpty表示队列中空位 g_hFull表示队列中非空位
HANDLE g_hEmpty, g_hFull;
//读数据线程函数
unsigned int __stdcall ReaderThreadFun(PVOID pM)
{
int nData = 0;
while (nData < 5)
{
WaitForSingleObject(g_hFull, INFINITE);
nData = g_arrDataQueue[g_i];
g_i = (g_i + 1) % QUEUE_LEN;
EnterCriticalSection(&g_cs);
printf("从队列中读数据%d\n", nData);
LeaveCriticalSection(&g_cs);
Sleep(rand() % 300);
ReleaseSemaphore(g_hEmpty, 1, NULL); //<拿走一个数据,循环队列多出来一个空位
}
return 0;
}
//写数据线程函数
unsigned int __stdcall WriterThreadFun(PVOID pM)
{
int nData = 0;
while (nData < 5)
{
WaitForSingleObject(g_hEmpty, INFINITE);
g_arrDataQueue[g_j] = ++nData;
g_j = (g_j + 1) % QUEUE_LEN;
EnterCriticalSection(&g_cs);
printf(" 将数据%d写入队列\n", nData);
LeaveCriticalSection(&g_cs);
Sleep(rand() % 300);
ReleaseSemaphore(g_hFull, 1, NULL);
}
return 0;
}
int main()
{
InitializeCriticalSection(&g_cs);
g_hEmpty = CreateSemaphore(NULL, QUEUE_LEN, QUEUE_LEN, NULL);
g_hFull = CreateSemaphore(NULL, 0, QUEUE_LEN, NULL);
g_i = g_j = 0;
HANDLE hThread[2];
hThread[0] = (HANDLE)_beginthreadex(NULL, 0, ReaderThreadFun, NULL, 0, NULL);
hThread[1] = (HANDLE)_beginthreadex(NULL, 0, WriterThreadFun, NULL, 0, NULL);
WaitForMultipleObjects(2, hThread, TRUE, INFINITE);
for (int i = 0; i < 2; i++)
CloseHandle(hThread[i]);
CloseHandle(g_hEmpty);
CloseHandle(g_hFull);
DeleteCriticalSection(&g_cs);
return 0;
}