具体先看一个例子
MutexLock mutex;
std::vector<Foo> foos;
void post(const Foo &f)
{
MutexLockGuard lock(mutex);
foos.push_back(f);
}
void tranverse()
{
MutexLockGuard lock(mutex);
for(std::vector<Foo>::const_iterator it=foos.begin();it!=foos.end();++it)
{
it->doit();
}
}
post加锁,然后修改foos对象;traverse加锁,然后遍历foos向量,这些都是正确的
将来有一天,Foo::doit()间接调用李post,那么就会很有戏剧性的结果
1.mutex非递归的,于是死锁了
2.mutex是递归的,由于push_back()可能(但不是总是)导致vector迭代器失效。程序偶尔会crash.
这个时候就体现出non-recursive的优越性,把程序的逻辑暴露出来,死锁比较容易debug