2015-11-27 2 views
0

Предположим, что у меня есть потоки производителей и потребителей, синхронизированные с использованием переменной условия.Переменные условий для атомных типов для синхронизации

// Approach 1 - Using condition variable 
mutex mmutex; 
condition_variable mcond; 
queue<string> mqueue; 

void producer(){ 
    while (true) { 
     unique_lock<mutex> lck(mmutex); 
     mqueue.push_back("Hello Hi"); 
     mcond.notify_one(); 
    } 
} 

void consumer{ 
    while (true){ 
     unique_lock<mutex> lck(mmutex); // locks mmutex 
     mcond.wait(); // releases mmutex; 
     string s = mqueue.front(); // locks mmutex again 
     mqueue.pop(); 
     mmutex.unlock(); 
    } 
} 

Как выше код сравнения для синхронизации с помощью простых атомных типов, а именно -

// Approach 2 - using atomics 
atomic_bool condition = false; 
condition_variable mcond; 
queue<string> mqueue; 

void producer(){ 
    unique_lock<mutex> lck(mmutex); 
    mqueue.push_back("Hello Hi"); 
    condition = true; 
} 

void consumer{ 
    while (1) { 
     if (condition == true) { 
      condition = false; 
      unique_lock<mutex> lck(mmutex); 
      mqueue.front(); 
      mqueue.pop(); 
      lck.unlock(); 
     } 
    } 
} 

Так, существуют переменные условия, я предполагаю, что они являются предпочтительным средством достижения синхронизации в таких случаях , Если это так, то почему переменные состояния являются лучшей альтернативой простой базе данных atomic_bool (или atomic_int, если вам нужно больше двух состояний)? Если нет, то каков наилучший способ добиться синхронизации в этом случае?

+1

'wait' необходимо вызвать с помощью замка. И вам нужно справиться с побочным пробуждением. –

+0

@ T.C. Вы уверены, что ожидание должно быть вызвано с блокировкой в ​​потребителе? Я был скопирован код из Tour of C++ by Bjarne Stroustrup. –

+0

Вы знаете, что ни одно из ваших решений не работает, если производитель быстрее, чем потребитель? Решение переменной условия также не обрабатывает ложные пробуждения. – Voo

ответ

3

Разница заключается в том, что переменная условия не потребляет циклы ЦП, пока другой поток ожидает ее. Если вы используете атомную переменную для синхронизации, вам нужно продолжать проверять ее значение в цикле.

+0

Если у вас многоядерный процессор, использует ли переменные условия все же результат повышения производительности по сравнению с другим подходом? –

+0

@FirstJens - да, это то, для чего они предназначены. Если у вас есть поток, сидящий в замкнутом цикле, ожидая, когда атомная переменная получит определенное значение, вы будете использовать циклы процессора, независимо от того, сколько у вас процессоров. –

+0

Занятое ожидание _may_ будет быстрее, чем использование переменной условия в особых случаях. Если все ваше приложение запускает 2 потока на двух процессорах (в частности, ваш выделенный выделенный процессор для потребительского потока) без конкуренции с другими приложениями, тогда ожидание ожидания может ускорить передачу данных между потоками. Переменные состояния выполняют дополнительную работу в обоих потоках, например. переключение на/из ядра, что не совсем дешево. В многозадачных средах, обычно теряющих процессор для оживленного ожидания, неприемлемо. –

Смежные вопросы