Multithreading C+中的多线程生产者/消费者+;
我正在研究多线程,并编写了一个基本的生产者/消费者程序。我与生产商/消费者有两个问题,如下所述。1) 即使将消费者睡眠时间设置为低于生产者睡眠时间,生产者似乎仍能更快地执行。2) 在consumer中,当生产者完成添加到队列中,但队列中仍然有元素时,我复制了代码。有没有关于更好地构建代码的建议Multithreading C+中的多线程生产者/消费者+;,multithreading,c++11,producer-consumer,Multithreading,C++11,Producer Consumer,我正在研究多线程,并编写了一个基本的生产者/消费者程序。我与生产商/消费者有两个问题,如下所述。1) 即使将消费者睡眠时间设置为低于生产者睡眠时间,生产者似乎仍能更快地执行。2) 在consumer中,当生产者完成添加到队列中,但队列中仍然有元素时,我复制了代码。有没有关于更好地构建代码的建议 #include <iostream> #include <queue> #include <mutex> class App { private: std:
#include <iostream>
#include <queue>
#include <mutex>
class App {
private:
std::queue<int> m_data;
bool m_bFinished;
std::mutex m_Mutex;
int m_ConsumerSleep;
int m_ProducerSleep;
int m_QueueSize;
public:
App(int &MaxQueue) :m_bFinished(false), m_ConsumerSleep(1), m_ProducerSleep(5), m_QueueSize(MaxQueue){}
void Producer() {
for (int i = 0; i < m_QueueSize; ++i) {
std::lock_guard<std::mutex> guard(m_Mutex);
m_data.push(i);
std::cout << "Producer Thread, queue size: " << m_data.size() << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(m_ProducerSleep));
}
m_bFinished = true;
}
void Consumer() {
while (!m_bFinished) {
if (m_data.size() > 0) {
std::lock_guard<std::mutex> guard(m_Mutex);
std::cout << "Consumer Thread, queue element: " << m_data.front() << " size: " << m_data.size() << std::endl;
m_data.pop();
}
else {
std::cout << "No elements, skipping" << std::endl;
}
std::this_thread::sleep_for(std::chrono::seconds(m_ConsumerSleep));
}
while (m_data.size() > 0) {
std::lock_guard<std::mutex> guard(m_Mutex);
std::cout << "Emptying remaining elements " << m_data.front() << std::endl;
m_data.pop();
std::this_thread::sleep_for(std::chrono::seconds(m_ConsumerSleep));
}
}
};
int main()
{
int QueueElements = 10;
App app(QueueElements);
std::thread consumer_thread(&App::Consumer, &app);
std::thread producer_thread(&App::Producer, &app);
producer_thread.join();
consumer_thread.join();
std::cout << "loop exited" << std::endl;
return 0;
}
#包括
#包括
#包括
类应用程序{
私人:
std::队列m_数据;
布尔姆·布菲完成;
std::mutex m_mutex;
int m_消费者睡眠;
国际生产商睡眠;
int m_队列大小;
公众:
应用程序(int和MaxQueue):m_bFinished(false)、m_ConsumerSleep(1)、m_ProducerSleep(5)、m_QueueSize(MaxQueue){}
无效生产者(){
对于(int i=0;i std::cout首先,您应该在使用者上使用条件变量而不是延迟。这样,使用者线程只有在队列不为空且生产者通知它时才会唤醒
也就是说,您的生产者调用更频繁的原因是生产者线程上的延迟。它是在保持互斥锁的同时执行的,因此消费者在延迟结束之前不会执行。您应该在调用sleep\u for
之前释放互斥锁:
for(int i=0;i
主要方案:
生产者在锁定状态下推送值,并向条件变量发出信号
使用者在锁定条件变量下等待,并检查谓词以防止虚假唤醒
我的版本:
#include <iostream>
#include <queue>
#include <mutex>
#include <thread>
#include <condition_variable>
#include <atomic>
class App {
private:
std::queue<int> m_data;
std::atomic_bool m_bFinished;
std::mutex m_Mutex;
std::condition_variable m_cv;
int m_QueueSize;
public:
App(int MaxQueue)
: m_bFinished(false)
, m_QueueSize(MaxQueue)
{}
void Producer()
{
for (int i = 0; i < m_QueueSize; ++i)
{
{
std::unique_lock<std::mutex> lock(m_Mutex);
m_data.push(i);
}
m_cv.notify_one();
std::cout << "Producer Thread, queue size: " << m_data.size() << std::endl;
}
m_bFinished = true;
}
void Consumer()
{
do
{
std::unique_lock<std::mutex> lock(m_Mutex);
while (m_data.empty())
{
m_cv.wait(lock, [&](){ return !m_data.empty(); }); // predicate an while loop - protection from spurious wakeups
}
while(!m_data.empty()) // consume all elements from queue
{
std::cout << "Consumer Thread, queue element: " << m_data.front() << " size: " << m_data.size() << std::endl;
m_data.pop();
}
} while(!m_bFinished);
}
};
int main()
{
int QueueElements = 10;
App app(QueueElements);
std::thread consumer_thread(&App::Consumer, &app);
std::thread producer_thread(&App::Producer, &app);
producer_thread.join();
consumer_thread.join();
std::cout << "loop exited" << std::endl;
return 0;
}
#包括
#包括
#包括
#包括
#包括
#include for end标志,当您处理并发线程时,因为理论上,m_bFinished
的值将存储在缓存线中,如果生产者线程中没有缓存失效,则可以从使用者线程中看不到更改的值。原子具有内存围栏,这保证了该值将是upda其他线程的ted
您也可以查看第页。谢谢您的回答,睡眠的目的纯粹是模拟不同的处理延迟,而不是最终代码的一部分。