gpt4 book ai didi

C++多线程生产者-消费者问题

转载 作者:行者123 更新时间:2023-12-03 13:13:55 26 4
gpt4 key购买 nike

我编写了一个带有条件变量的乘法生产者和消费者的代码。
即使我只有一个生产者和一个消费者,它也不起作用。
生产者和消费者都应该在 while(true) 中运行。
当我运行代码时,它会卡在大约 50% 的运行中。
我猜它会因过度等待而陷入僵局。
我没有成功调试它卡在哪里以及如何解锁条件。
根据要求,我必须创建带有等待、信号和广播的代码。

如果队列已满,则生产者正在等待。
如果队列为空,消费者正在等待。

void WaitableQueue::enqueue(size_t a_item)
{
(m_cond.getMutex()).lock();

while(m_itemsCounter==m_capacity && !m_isBeingDestroyed)
{
++m_numberOfWaiting;
m_cond.wait();
--m_numberOfWaiting;
}

std::cout<<"enqueue "<<a_item<<"\n";

m_queue.push(a_item);
++m_itemsCounter;
++m_numbOfProduced;
if(m_isBeingDestroyed)
{
m_cond.broadcast();
}

(m_cond.getMutex()).unlock();
m_cond.broadcast();
}

void WaitableQueue::dequeue()
{
(m_cond.getMutex()).lock();

while(m_itemsCounter==0 && !m_isBeingDestroyed)
{
++m_numberOfWaiting;
std::cout<<"Waiting\n";
m_cond.wait();
std::cout<<"Done waiting\n";
--m_numberOfWaiting;
}

if (m_isBeingDestroyed)
{
(m_cond.getMutex()).unlock();
m_cond.broadcast();
return;
}
std::cout<<"dequeue "<<m_queue.front()<<"\n";
m_queue.pop();
--m_itemsCounter;
++m_numbOfConsumed;
(m_cond.getMutex()).unlock();
m_cond.broadcast();
}

void WaitableQueue::destroy()
{
(m_cond.getMutex()).lock();
m_isBeingDestroyed=true;
(m_cond.getMutex()).unlock();
}



void Producer::run()
{
for(size_t i=0;i<m_numOfItemsToProduce;++i)
{
usleep(m_delay);
size_t item=produce();
m_wq.enqueue(item);
}
}


Producer::produce() const
{
return rand()%m_numOfItemsToProduce;
}

void Consumer::run()
{
m_numOfProducersMutex.lock();
while(m_numOfProducers>0)
{
m_numOfProducersMutex.unlock();
usleep(m_delay);
m_wq.dequeue();
m_numOfProducersMutex.lock();
}
m_numOfProducersMutex.unlock();
}


int main()
{
size_t numProducers=1;
size_t numConsumers=3;
Mutex mutex;
ConditionalVariable cond(mutex);

WaitableQueue<size_t> wq(NUM_OF_ITEMS,cond);
std::vector<Producer<size_t>*> producerArray;
std::vector<Consumer<size_t>*> consumerArray;
Mutex numOfProducersMutex;

for(size_t i=0;i<numProducers;++i)
{
Producer<size_t>* tempP=new Producer<size_t>(wq,NUM_OF_ITEMS,DELAY);
producerArray.push_back(tempP);
}

for(size_t i=0;i<numConsumers;++i)
{
Consumer<size_t>* tempC=new Consumer<size_t>(wq,numProducers,numOfProducersMutex,DELAY);
consumerArray.push_back(tempC);
}

for(size_t i=0;i<numProducers;++i)
{
producerArray[i]->start();
}

for(size_t i=0;i<numConsumers;++i)
{
consumerArray[i]->start();
}

for(size_t i=0;i<numProducers;++i)
{
producerArray[i]->join();
numOfProducersMutex.lock();
--numProducers;
numOfProducersMutex.unlock();
}
usleep(100);

//tell the consumers stop waiting
wq.destroy();
for(size_t i=0;i<numConsumers;++i)
{
consumerArray[i]->join();
}

for(size_t i=0;i<numProducers;++i)
{
delete producerArray[i];
}

for(size_t i=0;i<numConsumers;++i)
{
delete consumerArray[i];
}
}

它适用于大约 50% 的运行。
在其他 50% 中,它被卡住了。

最佳答案

要使用条件变量解决生产者-消费者问题,首先需要了解有界缓冲区问题。

在 C++ 中使用条件变量检查线程安全缓冲区队列的实现:
https://codeistry.wordpress.com/2018/03/08/buffer-queue-handling-in-multithreaded-environment/

您可以使用此缓冲区队列作为构建 block 来解决多生产消费者问题。
请在此处查看线​​程安全缓冲区队列如何用于解决 C++ 中的生产者-消费者问题:
https://codeistry.wordpress.com/2018/03/09/unordered-producer-consumer/

关于C++多线程生产者-消费者问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58251685/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com