2013-04-24 16 views
27

, maksimum güncellenmesi AncakMaksimum değeri atomik olarak nasıl güncellerim? Seri kodunda

template<typename T> 
void update_maximum(T& maximum_value, T const& value) noexcept 
{ 
    if(value > maximum_value) maximum_value = value; 
} 

tarafından basitçe başarılı olabilir, bu maksimum değer tutan bir atomic<T> değişken için nasıl yapılması gerektiğini: Açıkçası kodu

template<typename T> 
void update_maximum(std::atomic<T>& maximum_value, T const& value) noexcept 
{ 
    // want a lock-free, thread-safe implementation 
} 

Başka bir iş parçacığı yük ve mağaza arasında maximum_value değiştirebilir, çünkü seri sürümü çalışmıyor. Bunu uygulamak için compare_exchange (> yerine =='u karşılaştırır) kullanılabilir mi? Nasıl?

Açık kilitlere izin verilmediğini unutmayın (yalnızca izin verilen kilit, std::atomic<T>'un uygulanmasına neden olabilir).

cevap

30

Tek operasyonda mümkün görünmüyor, ancak sonuçta başarılı veya atomik değişkeni değeri büyük value daha olana kadar sen, bunu yapmaya çalışırsa bir döngü yapabilirsiniz:

template<typename T> 
void update_maximum(std::atomic<T>& maximum_value, T const& value) noexcept 
{ 
    T prev_value = maximum_value; 
    while(prev_value < value && 
      !maximum_value.compare_exchange_weak(prev_value, value)) 
     ; 
} 
+0

bu garantili iplik güvenli midir? – Walter

+1

@zch: "prev_value" yi döngü içinde güncellememeli misiniz? Aksi takdirde, ilk "compare_exchange_weak" başarısız olursa, her zaman bir _potentially_ "eski" değeriyle karşılaştırılır ve döngüden asla ayrılmayabilir. Ben haklı mıyım –

+1

@Walter, sanırım öyle, ama bunu test etmedim. @ André Neves, 'compare_exchange_weak' başarısız olduğunda güncelleme yapar - bu nedenle ilk argüman, const olmayan referanstır. – zch

İlgili konular