条件变量不起作用,但在添加 std::cout 后,它起作用了
The conditional variable is not working but after adding std::cout, it is working
我的项目由两个线程组成:一个主线程和另一个处理另一个 window 内容的线程。因此,当主线程想要请求另一个 windows 更新自身时,它会调用绘制函数,如下所示:
void SubApplicationManager::draw() {
// Zero number of applications which has finished the draw counter
{
boost::lock_guard<boost::mutex> lock(SubApplication::draw_mutex);
SubApplication::num_draws = 0;
}
// Draw the sub applications.
for (size_t i = 0; i < m_subApplications.size(); i++)
m_subApplications[i].signal_draw();
// Wait until all the sub applications finish drawing.
while (true){
boost::lock_guard<boost::mutex> lock(SubApplication::draw_mutex);
std::cout << SubApplication::num_draws << std::endl;
if (SubApplication::num_draws >= m_subApplications.size()) break;
}
}
draw 函数只是向另一个线程发出信号,表明已收到新任务。
void SubApplication::signal_draw() {
task = TASK::TASK_DRAW;
{
boost::lock_guard<boost::mutex> lock(task_received_mutex);
task_received = true;
}
task_start_condition.notify_all();
}
其他线程正文如下。它等待任务到达然后开始处理:
void SubApplication::thread() {
clock_t start_time, last_update;
start_time = last_update = clock();
//! Creates the Sub Application
init();
while (!done) // Loop That Runs While done=FALSE
{
// Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene()
if (active) // Program Active?
{
// Wait here, until a update/draw command is received.
boost::unique_lock<boost::mutex> start_lock(task_start_mutex);
while (!task_received){
task_start_condition.wait(start_lock);
}
// Task received is set to false, for next loop.
{
boost::lock_guard<boost::mutex> lock(task_received_mutex);
task_received = false;
}
clock_t frame_start_time = clock();
switch (task){
case TASK_UPDATE:
update();
break;
case TASK_DRAW:
draw();
swapBuffers();
break;
case TASK_CREATE:
create();
break;
default:
break;
}
clock_t frame_end_time = clock();
double task_time = static_cast<float>(frame_end_time - frame_start_time) / CLOCKS_PER_SEC;
}
}
}
问题是,如果我按原样 运行 代码,它永远不会 运行 另一个线程 task = TASK::TASK_DRAW;
但是如果我添加 std::cout << "Draw\n";
SubApplication::draw()
的开头,它将正常工作。我正在寻找它发生的原因以及通常的修复方法是什么?
作为初学者,在 task_start_mutex
锁下发出 task_start_condition
信号。
考虑在线程创建期间锁定该互斥锁以避免明显的竞争。
第三:您似乎有几个以 "logical tasks" 命名的互斥量(绘制,开始)。然而,实际上,互斥体保护资源,而不是 "logical tasks"。因此,最好以它们应该保护的共享资源来命名它们。 _(在这种情况下,我的印象是单个互斥体可能是 enough/better。但我们无法从显示的代码中确定))。
boost::lock_guard<boost::mutex> lock(task_received_mutex);
task_received = true;
好的,task_received_mutex
保护 task_received
。
boost::unique_lock<boost::mutex> start_lock(task_start_mutex);
while (!task_received){
task_start_condition.wait(start_lock);
}
哎呀,我们正在读取 task_received
,但没有持有保护它的互斥量。是什么阻止了一个线程读取 task_received
而另一个线程正在修改它的竞争?这可能会立即导致死锁。
此外,您的代码声称 "Wait until all the sub applications finish drawing" 但没有调用任何等待函数。所以它实际上是旋转而不是等待,这太糟糕了。
我的项目由两个线程组成:一个主线程和另一个处理另一个 window 内容的线程。因此,当主线程想要请求另一个 windows 更新自身时,它会调用绘制函数,如下所示:
void SubApplicationManager::draw() {
// Zero number of applications which has finished the draw counter
{
boost::lock_guard<boost::mutex> lock(SubApplication::draw_mutex);
SubApplication::num_draws = 0;
}
// Draw the sub applications.
for (size_t i = 0; i < m_subApplications.size(); i++)
m_subApplications[i].signal_draw();
// Wait until all the sub applications finish drawing.
while (true){
boost::lock_guard<boost::mutex> lock(SubApplication::draw_mutex);
std::cout << SubApplication::num_draws << std::endl;
if (SubApplication::num_draws >= m_subApplications.size()) break;
}
}
draw 函数只是向另一个线程发出信号,表明已收到新任务。
void SubApplication::signal_draw() {
task = TASK::TASK_DRAW;
{
boost::lock_guard<boost::mutex> lock(task_received_mutex);
task_received = true;
}
task_start_condition.notify_all();
}
其他线程正文如下。它等待任务到达然后开始处理:
void SubApplication::thread() {
clock_t start_time, last_update;
start_time = last_update = clock();
//! Creates the Sub Application
init();
while (!done) // Loop That Runs While done=FALSE
{
// Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene()
if (active) // Program Active?
{
// Wait here, until a update/draw command is received.
boost::unique_lock<boost::mutex> start_lock(task_start_mutex);
while (!task_received){
task_start_condition.wait(start_lock);
}
// Task received is set to false, for next loop.
{
boost::lock_guard<boost::mutex> lock(task_received_mutex);
task_received = false;
}
clock_t frame_start_time = clock();
switch (task){
case TASK_UPDATE:
update();
break;
case TASK_DRAW:
draw();
swapBuffers();
break;
case TASK_CREATE:
create();
break;
default:
break;
}
clock_t frame_end_time = clock();
double task_time = static_cast<float>(frame_end_time - frame_start_time) / CLOCKS_PER_SEC;
}
}
}
问题是,如果我按原样 运行 代码,它永远不会 运行 另一个线程 task = TASK::TASK_DRAW;
但是如果我添加 std::cout << "Draw\n";
SubApplication::draw()
的开头,它将正常工作。我正在寻找它发生的原因以及通常的修复方法是什么?
作为初学者,在 task_start_mutex
锁下发出 task_start_condition
信号。
考虑在线程创建期间锁定该互斥锁以避免明显的竞争。
第三:您似乎有几个以 "logical tasks" 命名的互斥量(绘制,开始)。然而,实际上,互斥体保护资源,而不是 "logical tasks"。因此,最好以它们应该保护的共享资源来命名它们。 _(在这种情况下,我的印象是单个互斥体可能是 enough/better。但我们无法从显示的代码中确定))。
boost::lock_guard<boost::mutex> lock(task_received_mutex);
task_received = true;
好的,task_received_mutex
保护 task_received
。
boost::unique_lock<boost::mutex> start_lock(task_start_mutex);
while (!task_received){
task_start_condition.wait(start_lock);
}
哎呀,我们正在读取 task_received
,但没有持有保护它的互斥量。是什么阻止了一个线程读取 task_received
而另一个线程正在修改它的竞争?这可能会立即导致死锁。
此外,您的代码声称 "Wait until all the sub applications finish drawing" 但没有调用任何等待函数。所以它实际上是旋转而不是等待,这太糟糕了。