我正在尝试创建一个多生产者和消费者计划。生产者生成随机数并将它们插入共享队列(共享内存),消费者打印出数字。用户使用以下参数调用程序:生产者线程数,使用者线程数和共享数据大小。
现在它只生产一个生产者(似乎)并且停止了。我想知道我是否可以帮助找出解锁消费者的方法。
这是队列标题
class SyncQueue
{
public:
SyncQueue(int sizeMax);
void enqueue(int value);
int dequeue();
private:
int MaxSize, front, rear, itemcounter;
std::vector<int> QueueElements;
std::mutex mutex;
//Condition variables for full and empty checks
std::condition_variable NotFull;
std::condition_variable NotEmpty;
};
这是队列功能
SyncQueue::SyncQueue(int sizeMax)
{
front = 0;
rear = 0;
MaxSize = sizeMax;
itemcounter = 0;
QueueElements.reserve(MaxSize);
}
void SyncQueue::enqueue(int value)
{
std::unique_lock<std::mutex> lock(mutex);
NotFull.wait(lock , [this](){return itemcounter != MaxSize; });
QueueElements[rear] = value;
rear = (rear + 1) % MaxSize;
++itemcounter;
NotEmpty.notify_all();
}
int SyncQueue::dequeue()
{
std::unique_lock<std::mutex> lock(mutex);
NotEmpty.wait(lock, [this](){return itemcounter != 0; });
int number = QueueElements[front];
front = (front + 1) % MaxSize;
--itemcounter;
NotFull.notify_all();
return number;
}
这是我创建线程的主要方法
std::vector<std::thread> producers(producerThreadCount);
std::vector<std::thread> consumers(consumerThreadCount);
SyncQueue queue(size);
//Build producer threads
for (int i = 0; i < producerThreadCount; i++)
{
producers[i] = std::thread(produceThread, i,std::ref(ProducerMutex), std::ref(queue), 200);
}
//Build consumers
for (int i = 0; i < consumerThreadCount; i++)
{
consumers[i] = std::thread(consumeThread, i, std::ref(ConsumerMutex), std::ref(queue), 400);
}
这些是生产和消费线程
void produceThread(int threadId, std::mutex &ProducerMutex, SyncQueue &sharedQueue, int time)
{
while (true)
{
int value = RandomNumberGenerator(std::ref(ProducerMutex));
sharedQueue.enqueue(value);
std::this_thread::sleep_for(std::chrono::milliseconds(time));
}
}
void consumeThread(int threadId, std::mutex &ConsumerMutex, SyncQueue &sharedQueue, int time)
{
while (true)
{
std::lock_guard<std::mutex> lock(ConsumerMutex);
int value;
std::cout << "Thread:" << threadId << " consumes:" <<sharedQueue.dequeue() << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(time));
}
}