这是我的代码,在这里我试图以分离模式访问两个不同线程中的资源,但无法读取第二个线程中m_dataLoaded的更新值。即使满足条件,它也会继续等待。我不了解其背后的逻辑以及如何实现此目标?
头文件 application.h
#ifndef APPLICATION_H
#define APPLICATION_H
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
class Application
{
public:
Application();
bool isDataLoaded();
void loadData();
void mainTask();
private:
bool m_dataLoaded;
std::condition_variable m_condVar;
std::mutex m_mutex;
};
#endif // APPLICATION_H
源文件 application.cpp
#include "application.h"
Application::Application()
: m_dataLoaded(false)
{
}
bool Application::isDataLoaded()
{
return m_dataLoaded;
}
void Application::loadData()
{
std::cout << "Inside loadData" << std::endl;
std::lock_guard<std::mutex> gaurd(m_mutex);
while(true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
m_dataLoaded = true;
if(m_dataLoaded)
{
m_condVar.notify_one();
}
}
}
void Application::mainTask()
{
std::cout << "Inside mainTask" << std::endl;
std::unique_lock<std::mutex> u_lock(m_mutex);
while(true)
{
std::cout << "Waiting..." << std::endl;
m_condVar.wait(u_lock, std::bind(&Application::isDataLoaded, this));
std::cout << "Start Data Processing: " << std::endl;
m_dataLoaded = false;
}
std::cout << "Break out of the loop" << std::endl;
}
主文件 main.cpp
#include "application.h"
int main()
{
Application *app = new Application;
std::thread *thread_1 = new std::thread(&Application::mainTask, app);
std::thread *thread_2 = new std::thread(&Application::loadData, app);
thread_2->detach();
thread_1->detach();
while(1)
{
}
return 0;
}
对于上面的代码,thread_1一直在等待... 我不明白为什么会这样。 任何帮助将不胜感激...
答案 0 :(得分:3)
并且在问题的注释部分被rafix07召集-main
可能会退出,并在任何线程有机会执行任何操作之前触发程序终止。但这不是您唯一的错误。
您忘记了跳出mainTask
中的循环。您的mainTask中的代码陷入了while(true)
循环中-即使isDataLoaded()
成为真实的表达式之后。
while (true) // <<=== INFINITE LOOP
{
std::cout << "Waiting..." << std::endl;
m_condVar.wait(u_lock, std::bind(&Application::isDataLoaded, this));
std::cout << "Start Data Processing: " << std::this_thread::get_id() << std::endl;
}
我喜欢传统的“循环”方法,因为它类似于先检查条件,然后等待,然后再检查(由于虚假唤醒)的pthreads模式。
while (!isDataLoaded())
{
std::cout << "Waiting..." << std::endl;
m_condVar.wait(u_lock);
}
std::cout << "Start Data Processing: " << std::this_thread::get_id() << std::endl;
或者不使用循环,只需使用谓词方法而不使用显式循环:
std::cout << "Waiting..." << std::endl;
m_condVar.wait(u_lock, [this]() {
return isDataLoaded();
});
std::cout << "Start Data Processing: " << std::this_thread::get_id() << std::endl;
这是您的完成程序,已更正:
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
class Application
{
public:
Application();
bool isDataLoaded();
void loadData();
void mainTask();
private:
bool m_dataLoaded;
std::condition_variable m_condVar;
std::mutex m_mutex;
};
Application::Application()
: m_dataLoaded(false)
{
}
bool Application::isDataLoaded()
{
return m_dataLoaded;
}
void Application::loadData()
{
std::cout << "Inside loadData" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::lock_guard<std::mutex> gaurd(m_mutex);
m_dataLoaded = true;
m_condVar.notify_all();
}
void Application::mainTask()
{
std::cout << "Inside mainTask" << std::endl;
std::unique_lock<std::mutex> u_lock(m_mutex);
while (!isDataLoaded())
{
std::cout << "Waiting..." << std::endl;
m_condVar.wait(u_lock);
}
std::cout << "Done Waiting" << std::endl;
}
int main()
{
Application *app = new Application;
std::thread *thread_1 = new std::thread(&Application::mainTask, app);
std::thread *thread_2 = new std::thread(&Application::loadData, app);
std::cout << "Thread_1 id: " << thread_1->get_id() << std::endl;
thread_2->detach();
thread_1->detach();
while (true)
std::this_thread::sleep_for(std::chrono::milliseconds(100000));
return 0;
}