2017-02-14 5 views
1

У меня есть класс проверки, который использует ah threadpool для обработки всех своих заданий.Как написать метод blockng waitUntil() в пул, который использует std :: atomics

Теперь, когда пользователь спрашивает, я начинаю поток, который передает мой класс проверки заданиями путем чтения с диска. И я уверен, что в какой-то момент чтение будет быстрее обработки. Поэтому я хочу написать метод, позволяющий этому потоку ждать, если будет обработано более 1000 заданий.

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

Моя попытка добавить метод была не такой приятной. И я знаю, что нужно использовать что-то лучше.

void Validator::waitUntilAvailable() { 
    while (m_blocksInFlight > 1000) { // thats my atomic 
     usleep(50000); // seems to be unavailable on Windows. 
    } 
} 

Может ли кто-нибудь здесь помочь в использовании метода опроса для решения моей проблемы?

спасибо.

+0

звучит как идеальный для использования семафора –

+0

... простой реализации здесь: https://gist.github.com/sguzman/9594227 –

+0

@RichardHodges выглядит как копия с HTTP: // stackoverflow.com/a/4793662/412080 –

ответ

1

Существует условие, что вы хотели бы подождать, но не ждать механизм ожидания.

Этот механизм std::condition_variable и std::mutex. Например:

class Validator 
{ 
    std::mutex m_mutex; 
    std::condition_variable m_condition; 
    std::atomic<int> m_blocksInFlight{0}; 

    bool test() const { 
     return m_blocksInFlight.load(std::memory_order_relaxed) > 1000; 
    } 

    void addJob() { 
     ++m_blocksInFlight; 

     // Only lock the mutex when the test succeeds. 
     if(this->test()) { 
      std::unique_lock<decltype(m_mutex)> lock(m_mutex); 
      m_condition.notify_one(); 
     } 
    } 

    void waitUntilAvailable() { 
     std::unique_lock<decltype(m_mutex)> lock(m_mutex); 
     while(!this->test()) 
      m_condition.wait(lock); 
    } 
}; 
+0

Я прочитал о состоянии, но не понял полностью, как это применимо. Как будет выглядеть код, уменьшающий атомный вид m_blocksInFlight? Я предполагаю, что это тоже нужно сделать с мьютексом? – Tom

+0

@Tom Обновлен код для вас. –