Страницы

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

воскресенье, 22 декабря 2019 г.

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

#cpp #многопоточность #cpp11 #mutex


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

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

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


Ответы

Ответ 1



В стандартной библиотеке готового семафора нет, по этому его надо писать самому, делая ожидание на 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(). Код усложнится, а выигрыш в производительности надо еще доказать.

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

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