返回原子,我应该在getter中使用临时线程安全吗?

doc*_*doc 5 c++ getter multithreading atomic thread-safety

是否有必要在这里使用临时线程安全?

 int getVal() {
       this->_mutex.lock();
       int result = this->_val;
       this->_mutex.unlock();
       return result;
 }
Run Code Online (Sandbox Code Playgroud)

我会给你拆卸简单的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   
Run Code Online (Sandbox Code Playgroud)

编译器是gcc/g ++ 3.4.5

Jam*_*lis 5

如果访问this->_val是同步的this->_mutex,那么您没有选择当前编写代码的方式.您需要this->_val在解锁互斥锁之前阅读,并且必须在返回之前解锁互斥锁.该result变量是获得此操作顺序所必需的.

如果使用lock_guard(或scoped_lock在Boost中),则不需要使用临时,因为当函数返回时,互斥锁上的锁将被释放.例如,使用C++ 0x线程库:

int getVal() {
    std::lock_guard<std::mutex> lock(_mutex);
    return this->_val;
}   // lock is released by lock_guard destructor 
Run Code Online (Sandbox Code Playgroud)

  • @doc:我用汇编语言输出编译了James的代码:它将成员变量读取到%ebx,然后调用lock_guard的析构函数,然后将%ebx复制到%eax并清理堆栈/返回.gcc 4.4.4 (3认同)
  • @doc:什么不会?只有在要返回的对象的副本完成之后,才会销毁局部变量`lock`. (2认同)