我的项目由两个线程组成:一个主线程,另一个处理另一个窗口内容的线程。因此,当主线程想要求另一个窗口更新自己时,它调用如下所示的绘制函数:
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;
}
}绘制函数只是向另一个线程发出信号,表示接收到了一个新任务。
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;运行另一个线程,但是如果我在SubApplication::draw()的开头添加了一个std::cout << "Draw\n";,它就会正常工作。我正在寻找它发生的原因,以及修复它的通常方法是什么?
发布于 2015-06-15 09:28:16
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,而另一个线程正在修改它呢?这可能立即导致僵局。
此外,您的代码声称“等待直到所有子应用程序完成绘图”,但没有调用任何等待函数。因此,它实际上是旋转而不是等待,这是可怕的。
发布于 2015-06-15 09:23:15
首先,在task_start_condition锁下向task_start_mutex发送信号。
考虑在线程创建期间锁定该互斥锁,以避免明显的竞争。
第三:您似乎有几个以“逻辑任务”命名的互斥对象(绘制、开始)。然而,在现实中,互斥保护资源,而不是“逻辑任务”。因此,用他们应该保护的共享资源来命名他们是很好的做法。_(在这种情况下,我得到的印象是一个互斥可以足够/更好)。但我们不能从所示的代码中确定))。
https://stackoverflow.com/questions/30839734
复制相似问题