【发布时间】:2014-04-29 17:49:26
【问题描述】:
据我所知,在 lock_guard 被删除和函数(在另一个线程中运行)实际返回之间有相当长的时间。请参阅下面的评论 TEST(...)
bool bDone = false;
void run_worker(Foo* f) {
f->Compute();
bDone = true;
}
TEST(FooTest,ThreadFoo) {
Foo* f = makeFoo();
std::thread worker( run_worker, f );
worker.detach();
micro_wait(100); // wait for N microseconds
f->Reset(); // should block until Compute() is done
// !!?? Why is this necessary !?!?
int k=0;
while(++k<500 && !bDone)
micro_wait(100);**
EXPECT_TRUE(bDone); // Fails even with a single micro_wait(100)!
}
对于何时/为什么会有这样的时间流逝是否有很好的解释 在 f->Compute() 完成和 bDone 设置之间?我的怀疑是互斥锁被解锁,而仍然需要清理在 Compute() 中分配的基于堆栈的变量,但这纯粹是一个假设。
用于计算和重置的存根如下:
void Foo::Compute() {
std::lock_guard<std::mutex> guard(m_Mutex);
// ... allocate bunch of temporary stuff on stack, update *this
}
void Foo::Reset() {
std::lock_guard<std::mutex> guard(m_Mutex);
// ... simpler stuff, clear
}
【问题讨论】:
-
这段代码看起来很破。不能保证
Compute会在Reset之前获得锁。此外,bDone的访问也没有同步。享受你未定义的行为。 -
对,这种情况最好用 std::future + std::async;出于本实验的目的,第一个 micro_wait(100) 会阻止 Reset 首先获得锁。我只是想解释一下在 Compute 之后为 bool 变量赋值的下一条语句如何在 Reset 完成之前无法完成。
标签: c++ multithreading c++11 locking mutex