2012-10-05 59 views

回答

0

這取決於你的架構,但在總體上是不可能做到這一點在C

通常比較和交換與從一個位置原子加載到內存和存儲值的指令來實現如果內存中的位置與您指定的某個現有值相匹配,則返回該位置。

至少在x86上,如果值不匹配,則沒有規定僅執行此加載。也不清楚你爲什麼想要這樣做。也許另一種架構會支持這樣的事情,但那會取決於架構,而不是以便攜方式在C中完成的事情。

+0

在現代x86處理器中沒有cmov指令嗎?它是否符合所需的配置文件? –

+0

我不認爲這會起作用,因爲在執行cmov之前,您需要一條指令來設置條件代碼。因此,在檢查條件代碼和執行cmov之間的時間內,另一個處理器可能會更改您嘗試寫入的內存中的值。 –

+0

我明白了。感謝您的解釋! =) –

4

如何:

void compare_and_swap_if_not_equal(word_t const required_non_value, word_t const new_value, word_t* ptr_to_shared_variable) { 
    for (;;) { 
     word_t const snapshot_value = *ptr_to_shared_variable; 
     if (required_non_value == snapshot_value) { 
      break; 
      // or (sleep and) 'continue;', if you want to wait for the stored value to be different 
      // -- but you might of course miss a transient change to a different state and back. 
     } else { 
      if (compare_and_swap_if_equal(ptr_to_shared_variable, snapshot_value, new_value)) { 
       // we know the stored value was different; if this 'theory' still matches reality: swap! done! 
       break; 
      } 
     } 
    } 
} 

未經檢驗。未編譯的。使用'const'是因爲我喜歡這種方式:)。 'word_t'是一個類型佔位符,我不知道真正的類型應該是什麼。我不知道在stdatomic.h中如何調用'compare_and_swap_if_equal'。

(已添加)atomic_compare_exchange_weak()是票據。出於某種原因,它需要一個指向 '預期' 的說法,所以你必須修改上面的代碼

如果(atomic_compare_exchange_weak(ptr_to_shared_variable,& snapshot_value,NEW_VALUE))...

'弱'版本應該在上面的代碼中工作;虛假地返回「虛假」只會在循環中添加另一行程。仍未編譯,未經測試;在家裏不要依賴這個代碼。

+0

+1這對我來說似乎也是正確的。 – Tudor

+0

如果指點者在採取'snapshot_value'和原子cas之間總是發生變化怎麼辦?看起來循環永遠不會結束。另外,在取指點物之前我們不需要記憶障礙嗎? (原子cas暗示它) –

+1

@IgorR。回覆:'如果指點者在拍攝snapshot_value和原子cas之間總是發生變化呢?':是的,我想這在真正不公平的系統中是可能的。超時或重試計數器可能是一個選項。人們可能會想知道將是什麼樣的系統和工作,以及爲什麼作家和讀者不會更好地合作:)。另外,我想這也會發生在CAS'的典型應用中,如果'相同',甚至更多,因爲實際工作是在初始獲取和CAS之間完成的。 –