是否有必要在此使用临时线程安全?
int getVal() {
this->_mutex.lock();
int result = this->_val;
this->_mutex.unlock();
return result;
}
我会给你反汇编简单的RAII测试函数
int test()
{
RAIITest raii; //let's say it's a scoped lock
return 3;
}
{
0x004013ce <_Z4testv>: push %ebp
0x004013cf <_Z4testv+1>: mov %esp,%ebp
0x004013d1 <_Z4testv+3>: sub $0x28,%esp
return 3;
0x004013d4 <_Z4testv+6>: lea -0x18(%ebp),%eax
0x004013d7 <_Z4testv+9>: mov %eax,(%esp)
0x004013da <_Z4testv+12>: call 0x4167a0 <_ZN8RAIITestD1Ev> //here destructor is called
0x004013df <_Z4testv+17>: mov $0x3,%eax //here result is pushed onto the stack
}
0x004013e4 <_Z4testv+22>: leave
0x004013e5 <_Z4testv+23>: ret
编译器是gcc / g ++ 3.4.5
答案 0 :(得分:5)
如果this->_val
同步对this->_mutex
的访问,则您无法选择当前编写代码的方式。在解锁互斥锁之前,您需要阅读this->_val
,并且必须在返回之前解锁互斥锁。 result
变量是获得此操作顺序所必需的。
如果你在Boost中使用lock_guard
(或scoped_lock
),则不需要使用临时值,因为当函数返回时,互斥锁上的锁将被释放。例如,使用C ++ 0x线程库:
int getVal() {
std::lock_guard<std::mutex> lock(_mutex);
return this->_val;
} // lock is released by lock_guard destructor
答案 1 :(得分:1)
如果使用显式锁定()/ unlock(),则为是。否,如果您在堆栈上构造一个锁定对象并让其析构函数执行解锁。
答案 2 :(得分:0)
否 - 编译器自动为返回值创建临时值。您通常也不需要使用互斥锁保护读取,因此即使它是多线程的,只需return _val;
即可。
顺便说一下,我已经摆脱了领先的下划线 - 关于什么变量名称,当它们以下划线开头时可以使用和不能使用的规则非常复杂,最好完全避免它们。
答案 3 :(得分:0)
你可以干净利落地完成这项工作,你的互斥锁被封装在一个scoped_lock中,可以在销毁时解锁:
int getVal() {
scoped_lock lockit(_mutex);
return _val;
}
是的,你需要保持锁定直到它被返回。