И был вызван 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;
Вот ваша программа comlete, измененная с исправлениями:
#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;
}