啊啦啦啦来了 2021-05-16 19:16 采纳率: 33.3%
浏览 56
已采纳

多生产者多消费者问题C++实现,为什么始终只有一个消费者线程工作?

#include <iostream> 
#include <windows.h>
#include <unordered_map>
#include <string>

using namespace std;

typedef int semaphore;                          /* 信号量是一种特殊的整型变量 */
const int SIZE_OF_BUFFER =3;                                //缓冲区长度 
const unsigned short PRODUCERS_COUNT = 5;       //生产者的个数 
const unsigned short CONSUMERS_COUNT = 5;       //消费者的个数 

DWORD producers[PRODUCERS_COUNT]; //生产者线程的标识符                       
DWORD consumers[CONSUMERS_COUNT];//消费者线程的标识符 

const unsigned short THREADS_COUNT = PRODUCERS_COUNT + CONSUMERS_COUNT; //总的线程数 

/**
*定义信号量
*/
HANDLE mutex;                               //互斥信号量  
HANDLE full;                             //表示放有产品的缓冲区数,其初值为0  
HANDLE eempty;                            //表示可供使用的缓冲区数,其初值为N  

/**
*定义共享缓冲区
*/
semaphore buffer[SIZE_OF_BUFFER];

unordered_map<DWORD, string>  threadName;      //用一个哈希表存储线程ID与线程名字之间的对应关系
int producerNum = 0;                        //创建哈希表的辅助变量
int consumerNum = 0;

/**
*定义生产者和消费者使用的指针
*/
int in = 0;
int out = 0;

int productNum = 0;


void enBuffer(int pos)
{
    cout << "正在生产产品..." << endl;
    buffer[pos] = 1;
    productNum++;
    cout << "生产完成!    已生产" << productNum << "个产品,并将新产品放在了缓冲区位置:" << pos << endl;
    for (int i = 0; i < SIZE_OF_BUFFER; i++)
        cout << buffer[i] << ' ';
    cout << endl;
}

void deBuffer(int pos)
{
    cout << "正在消费产品..." << endl;
    buffer[pos] = 0;
    productNum--;
    cout << "已消费在缓冲区位置:" << pos << "的产品,缓冲区剩余空间:" << SIZE_OF_BUFFER - productNum << endl;
    for (int i = 0; i < SIZE_OF_BUFFER; i++)
        cout << buffer[i] << ' ';
    cout << endl;
    cout << endl;
}

/**
*生产者
*/
DWORD WINAPI Producer(LPVOID lpParam)
{
    while (1)
    {
        WaitForSingleObject(eempty, INFINITE);  // P(empty) 生产者信号量 -1  
        WaitForSingleObject(mutex, INFINITE);  // P(mutex) 获取线程间互斥信号  
        enBuffer(in);

        if (threadName.find(GetCurrentThreadId()) == threadName.end()) {
            string temp = "生产者";
            temp += '0' + producerNum;
            threadName.insert({ GetCurrentThreadId() ,temp });
            producerNum++;
        }
        cout << threadName[GetCurrentThreadId()]<<endl<<endl;

        in = (in + 1) % SIZE_OF_BUFFER;
        ReleaseMutex(mutex);                  // V(mutex) 释放线程间互斥信号  
        ReleaseSemaphore(full, 1, NULL);        // V(full) 消费者信号量 +1  

    }
    return 0;
}

/**
*消费者
*/
DWORD WINAPI Consumer(LPVOID lpPara)
{
    while (1)
    {
        WaitForSingleObject(full, INFINITE);        //P(full) 消费者信号量-1  
        WaitForSingleObject(mutex, INFINITE);       //P(mutex) 获得线程间互斥信号  
        deBuffer(out);

        if (threadName.find(GetCurrentThreadId()) == threadName.end()) {
            string temp = "消费者";
            temp += '0' + consumerNum;
            threadName.insert({ GetCurrentThreadId() ,temp });
            consumerNum++;
        }
        cout << threadName[GetCurrentThreadId()] << endl << endl;

        out = (out + 1) % SIZE_OF_BUFFER;
        ReleaseMutex(mutex);                       //V(mutex) 释放线程间互斥信号  
        ReleaseSemaphore(eempty, 1, NULL);            //V(empty) 生产者信号量+1  

    }
    return 0;
}

int main()
{
    //创建Mutex和Semaphore 
    mutex = CreateMutex(NULL, FALSE, NULL);
    full = CreateSemaphore(NULL, 0, SIZE_OF_BUFFER, NULL);
    eempty = CreateSemaphore(NULL, SIZE_OF_BUFFER, SIZE_OF_BUFFER, NULL);

    for (int i = 0; i < SIZE_OF_BUFFER; i++)
        buffer[i] = -1;

    HANDLE PVThreads[THREADS_COUNT];     //各线程的handle  


     //创建生产者线程 
    for (int i = 0; i < PRODUCERS_COUNT; i++) {
        PVThreads[i] = CreateThread(NULL, 0, Producer, NULL, 0, &producers[i]);
        if (PVThreads[i] == NULL) break;
    }
    //创建消费者线程  
    for (int i = 0; i < CONSUMERS_COUNT; i++) {
        PVThreads[PRODUCERS_COUNT + i]
            = CreateThread(NULL, 0, Consumer, NULL, 0, &consumers[i]);
        if (PVThreads[i] != NULL) break;
    }

    bool isContinue = true;
    while (isContinue)
    {
        if (getchar()) {  //按回车后终止程序运行 
            isContinue = false;
        }
    }
    system("PAUSE");
    return 0;
}
  • 写回答

3条回答 默认 最新

  • CSDN专家-三岁丫 2021-05-16 19:43
    关注

    if (PVThreads[i] != NULL) break; 是这句话的逻辑有问题吧,应该是 == 吧

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 Qt下使用tcp获取数据的详细操作
  • ¥15 idea右下角设置编码是灰色的
  • ¥15 全志H618ROM新增分区
  • ¥15 在grasshopper里DrawViewportWires更改预览后,禁用电池仍然显示
  • ¥15 NAO机器人的录音程序保存问题
  • ¥15 C#读写EXCEL文件,不同编译
  • ¥15 MapReduce结果输出到HBase,一直连接不上MySQL
  • ¥15 扩散模型sd.webui使用时报错“Nonetype”
  • ¥15 stm32流水灯+呼吸灯+外部中断按键
  • ¥15 将二维数组,按照假设的规定,如0/1/0 == "4",把对应列位置写成一个字符并打印输出该字符