簡體   English   中英

是返回原子的,我應該在getter中使用臨時變量來確保線程安全嗎?

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

是否有必要在此處使用臨時線程安全線程?

 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

如果對this->_val訪問由this->_val this->_mutex同步,則您無法選擇當前編寫代碼的方式。 在解鎖互斥鎖之前,您需要閱讀this->_val ,並且在返回之前必須解鎖互斥鎖。 result變量是獲得此操作順序所必需的。

如果使用lock_guard (或Boost中的scoped_lock ),則無需使用臨時選項,因為互斥鎖將在函數返回時釋放。 例如,使用C ++ 0x線程庫:

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

是的,如果您使用顯式lock()/ unlock()。 如果您在堆棧上構造一個鎖定對象並讓其析構函數進行解鎖,則不會。

否-編譯器會自動為返回值創建一個臨時值。 通常,您也不需要使用互斥量來保護讀取,因此即使它是多線程的,也只需return _val; 應該足夠了。

順便說一句,我會擺脫下划線的困擾-有關在下划線開頭時可以使用和不能使用哪些變量名的規則非常復雜,最好完全避免使用它們。

您可以干凈地執行此操作,因為您的互斥鎖封裝在scoped_lock中,該鎖在銷毀時會解鎖:

 int getVal() {
       scoped_lock lockit(_mutex);
       return _val;
 }

是的,您確實需要按住該鎖,直到歸還為止。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM