2015-09-27 37 views
0
void method1() { 
    if (is_true) { 
     mutex1.lock(); 
     condition_var.wait(mutex1, 
           [=] { return is_true == false; }); 
     mutex1.unlock(); 
    } 
    // do some work 
} 


void method2() { 
    if (is_true) { 
     mutex1.lock(); 
     condition_var.wait(mutex1, 
           [=] { return is_true == false; }); 
     mutex1.unlock(); 
    } 
    // do some work 
} 

void method3() { 
    mutex2.lock(); 
    is_true = true; 
    // do some job 
    mutex1.lock(); 
    is_true = false; 
    condition_var.notify_all(); 
    mutex1.unlock(); 
    mutex2.unlock(); 
} 

method1method2可以同時執行,不需要有任何的自我同步,同步method3本身mutex2method1/method2無法與method3同時運行此condition_varis_true使用布爾值以及mutex1。 我在這裏關心的是mutex1創建了一個代碼區,其中method1method2被阻止其併發行爲。但我無法刪除此互斥鎖,因爲is_true = false; condition_var.notify_all();必須是原子操作。 如何重新設計它以從method1method2中刪除鎖定?併發排除調整

回答

1

你的代碼沒有問題。條件變量實際上沒有狀態。如果您在wait之前致電notify,它將無限等待。所以你必須手動執行狀態is_true並使用互斥鎖來防止競爭條件。

您還可以使用事件對象(Windows的CreateEvent,Linux的信號量),但效率會更低。 std::mutex的實現使用快速自旋鎖,並且只有在自旋鎖定超時後纔會進行緩慢的系統調用。代碼的保護部分很短,所以鎖不會影響性能。

+0

實際上,無處可以保證'std :: mutex'通過_futex_實現。所以'std :: mutex :: lock()'只有在被鎖定時纔會很昂貴(因爲阻塞)。 – Nevermore