生产者消费者问题——C++ windows版 多生产者多消费者的队列实现

#include "public.h"
#include 
#include 
#include 
CRITICAL_SECTION g_cs;                  // mutex

HANDLE    emptyBufferSemaphore;      //
HANDLE    fullBufferSemaphore;       //

#define INVALID  -1

#define PRODUCER 5
#define CUSTOMER 5

#define NUM_COUNT 8
#define BUFF_SIZE 4

static std::queue<int> bufferQueue;
static std::map< DWORD, int > countMap;

bool ProducerFinish = false;

//设置控制台输出颜色
BOOL SetConsoleColor(WORD wAttributes)
{
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    if (hConsole == INVALID_HANDLE_VALUE)
        return FALSE;
    return SetConsoleTextAttribute(hConsole, wAttributes);
}

DWORD WINAPI Producer(LPVOID param)
{
    while (true)
    {
        WaitForSingleObject(emptyBufferSemaphore, INFINITE);

        EnterCriticalSection(&g_cs);

        unsigned int threadId = GetCurrentThreadId();
        if (countMap.find(threadId) == countMap.end())
            countMap[threadId] = 0;

        int productID = ++countMap[threadId];

        bufferQueue.push(productID);
        printf("生产者 %d , 生产%d\n", threadId, productID);

        if (productID == NUM_COUNT)
        {
            SetConsoleColor(FOREGROUND_RED);
            printf("生产者 %d 生产完毕\n", GetCurrentThreadId());
            SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);

            LeaveCriticalSection(&g_cs);
            ReleaseSemaphore(fullBufferSemaphore, 1, NULL);

            break;
        }

        LeaveCriticalSection(&g_cs);

        ReleaseSemaphore(fullBufferSemaphore, 1, NULL);
    }

    return NULL;
}

DWORD WINAPI Customer(LPVOID param)
{
    while (true)
    {
        WaitForSingleObject(fullBufferSemaphore, INFINITE);

        EnterCriticalSection(&g_cs);

        int buffer = -1;

        if (!bufferQueue.empty())
        {
            buffer = bufferQueue.front();
            bufferQueue.pop();
        }

        if (buffer != INVALID)
            printf("消费者%d ,消费%d\n", GetCurrentThreadId(), buffer);

        if (bufferQueue.empty() && ProducerFinish)
        {
            printf("消费者%d 结束\n", GetCurrentThreadId());
            LeaveCriticalSection(&g_cs);

            // 通知其他消费者可以结束了
            ReleaseSemaphore(fullBufferSemaphore, 1, NULL);
            break;
        }

        LeaveCriticalSection(&g_cs);

        ReleaseSemaphore(emptyBufferSemaphore, 1, NULL);
    }


    return NULL;
}

int main(int argc, char** argv)
{
    InitializeCriticalSection(&g_cs);

    emptyBufferSemaphore = CreateSemaphore(NULL, 4, 4, NULL);
    fullBufferSemaphore = CreateSemaphore(NULL, 0, 4, NULL);

    HANDLE producerThreads[PRODUCER];
    HANDLE customerThreads[CUSTOMER];

    for (int i = 0; i < PRODUCER; ++i)
    {
        producerThreads[i] = CreateThread(NULL, 0, Producer, NULL, NULL, NULL);
    }

    for (int i = 0; i < CUSTOMER; ++i)
        customerThreads[i] = CreateThread(NULL, 0, Customer, NULL, NULL, NULL);


    WaitForMultipleObjects(PRODUCER, producerThreads, TRUE, INFINITE);

    ProducerFinish = true;

    WaitForMultipleObjects(CUSTOMER, customerThreads, TRUE, INFINITE);

    for (int i = 0; i < PRODUCER; ++i)
        CloseHandle(producerThreads[i]);

    for (int i = 0; i < CUSTOMER; ++i)
        CloseHandle(customerThreads[i]);

    CloseHandle(emptyBufferSemaphore);
    CloseHandle(fullBufferSemaphore);
    DeleteCriticalSection(&g_cs);
    countMap.clear();

    return 0;
}

你可能感兴趣的:(C++)