Читаем Параллельное программирование на С++ в действии полностью

   this_thread_interrupt_flag.clear_condition_variable();

  }

 };

};

void interruptible_wait(std::condition_variable& cv,

 std::unique_lock& lk) {

 interruption_point();

 this_thread_interrupt_flag.set_condition_variable(cv);

 interrupt_flag::clear_cv_on_destruct guard;

 interruption_point();

 cv.wait_for(lk, std::chrono::milliseconds(1));

 interruption_point();

}

Если мы ждем какой-то предикат, то таймаут продолжительностью 1 мс можно полностью скрыть внутри цикла проверки предиката:

template

void interruptible_wait(std::condition_variable& cv,

 std::unique_lock& lk,

 Predicate pred) {

 interruption_point();

 this_thread_interrupt_flag.set_condition_variable(cv);

 interrupt_flag::clear_cv_on_destruct guard;

 while (!this_thread_interrupt_flag.is_set() && !pred()) {

  cv.wait_for(lk, std::chrono::milliseconds(1));

 }

 interruption_point();

}

Правда, предикат при этом проверяется чаще, чем необходимо, но зато эту функцию легко использовать вместо простого вызова wait(). Легко реализовать и другие варианты функций с таймаутом, например: ждать в течение указанного времени или 1 мс в зависимости от того, что меньше.

Ну хорошо, с ожиданием std::condition_variable мы разобрались, а что сказать о std::condition_variable_any? Всё точно так же или можно сделать лучше?

<p>9.2.4. Прерывание ожидания <code>std::condition_variable_any</code></p>

Класс std::condition_variable_any отличается от std::condition_variable тем, что работает с любым типом блокировки, а не только с std::unique_lock. Как выясняется, это сильно упрощает дело, так что мы сможем добиться более впечатляющих результатов, чем получилось с std::condition_variable. Раз допустим любой тип блокировки, то можно написать и свой собственный класс, который захватывает (освобождает) как внутренний мьютекс set_clear_mutex в классе interrupt_flag, так и блокировку, переданную при вызове wait(). Соответствующий код приведён в листинге ниже.

Листинг 9.12. Реализация interruptible_wait() для std::condition_variable_any

class interrupt_flag {

 std::atomic flag;

 std::condition_variable* thread_cond;

 std::condition_variable_any* thread_cond_any;

 std::mutex set_clear_mutex;

public:

 interrupt_flag():

  thread_cond(0), thread_cond_any(0) {}

 void set() {

  flag.store(true, std::memory_order_relaxed);

  std::lock_guard lk(set_clear_mutex);

  if (thread_cond) {

   thread_cond->notify_all();

  } else if (thread_cond_any) {

   thread_cond_any->notify_all();

  }

 }

 template

 void wait(std::condition_variable_any& cv, Lockable& lk) {

  struct custom_lock {

   interrupt_flag* self;

   Lockable& lk;

   custom_lock(interrupt_flag* self_,

    std::condition_variable_any& cond,

    Lockable& lk_): self(self_), lk(lk_) {

    self->set_clear_mutex.lock();  ←(1)

    self->thread_cond_any = &cond ←(2)

   }

   void unlock() { ←(3)

    lk.unlock();

    self->set_clear_mutex.unlock();

   }

   void lock() {

    std::lock(self->set_clear_mutex, lk); ←(4)

   }

   ~custom_lock() {

    self->thread_cond_any = 0; ←(5)

    self->set_clear_mutex.unlock();

   }

  };

  custom_lock cl(this, cv, lk);

  interruption_point();

  cv.wait(cl);

  interruption_point();

 }

 // остальное, как и раньше

};

template

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных