Страницы

Поиск по вопросам

четверг, 15 ноября 2018 г.

Как наиболее корректно реализовать mutex со счетчиком?

Пусть, например, задача - ограничить количество одновременно работающих потоков. Т.е. хочется иметь мьютекс, который бы могли захватывать одновременно N потоков, а остальные бы ждали, пока один из потоков не освободит такой мьютекс.
Вижу несколько вариантов организации такой функциональности, например, с использованием переменной для подсчета и обычных мьютексов, но что-то мне кажется, что я изобретаю велосипед.
Как наиболее корректно реализовать такой семафор со счетчиком средствами стандартного C++11? (Или там это уже есть, и я просто плохо читал литературу?..)


Ответ

В стандартной библиотеке готового семафора нет, по этому его надо писать самому, делая ожидание на condition_variable
В простейшем варианте это
class Semaphore { public: explicit Semaphore(int max_count) : max_count_(max_count) {}
void acquire() { std::unique_lock lock(mut_); while (count_ == max_count_) cv_.wait(lock); ++count_; }
void release() { std::lock_guard lock(mut_); assert(count_ > 0); --count_; cv_.notify_one(); }
private: int max_count_; int count_ = 0; std::mutex mut_; std::condition_variable cv_; };
Вызов notify в release() можно вынести из под мьютекса. Но на некоторых реализациях это не нужно
Вместо мьютекса в release() можно использовать атомарную переменную count_, но это потребует CAS в acquire(). Код усложнится, а выигрыш в производительности надо еще доказать.

Комментариев нет:

Отправить комментарий