Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is return atomic and should I use temporary in getter to be thread safe?

Is it necessary to use a temporary here to be thread-safe?

 int getVal() {
       this->_mutex.lock();
       int result = this->_val;
       this->_mutex.unlock();
       return result;
 }

I'll give you disassembly of simple RAII test function

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   

the compiler is gcc/g++ 3.4.5

like image 614
mip Avatar asked Sep 03 '10 19:09

mip


People also ask

Are atomic values thread-safe?

Atomic classes allow us to perform atomic operations, which are thread-safe, without using synchronization. An atomic operation is executed in one single machine-level operation.

Is atomic thread-safe C++?

In order to solve this problem, C++ offers atomic variables that are thread-safe. The atomic type is implemented using mutex locks. If one thread acquires the mutex lock, then no other thread can acquire it until it is released by that particular thread.


2 Answers

If access to this->_val is synchronized by this->_mutex, then you don't have a choice the way the code is written currently. You need to read this->_val before you unlock the mutex and you have to unlock the mutex before you return. The result variable is necessary to get this order of actions.

If you use a lock_guard (or scoped_lock in Boost), then you don't need to use the temporary because the lock on the mutex will be released when the function returns. For example, using the C++0x threads library:

int getVal() {
    std::lock_guard<std::mutex> lock(_mutex);
    return this->_val;
}   // lock is released by lock_guard destructor 
like image 191
James McNellis Avatar answered Oct 22 '22 18:10

James McNellis


Yes if you use explicit lock()/unlock(). No if you construct a lock object on the stack and have its destructor do the unlock.

like image 45
usta Avatar answered Oct 22 '22 18:10

usta