vendredi 21 février 2020

Why in std::condition_variable notify_all works faster than notify_one (on random requests)?

I wrote my implementation of std::shared_mutex, but on my tests it worked for several minutes, replaced notify_one with notify_all, it began to work for 20 milliseconds. This is because of the overhead of waking up exactly one conditional variable, why it works more slowly than that notify_all.

class RWLock {
public:
    template <class Func>
    void Read(Func func) {
        std::unique_lock<std::mutex> lock(mutex_);
        no_writer_.wait(lock, [this] { return !write_; });
        ++read_cnt_;
        lock.unlock();

        try {
            func();
        } catch (...) {
            End();
            throw;
        }
        End();
    }

    template <class Func>
    void Write(Func func) {
        std::unique_lock<std::mutex> lock(mutex_);
        no_readers_.wait(lock, [this] { return read_cnt_ == 0; });

        write_ = true;
        try {
            func();
        } catch (...) {
            write_ = false;
            throw;
        }

        write_ = false;

        no_writer_.notify_all();
    }

private:
    std::mutex mutex_;
    std::condition_variable no_writer_;
    std::condition_variable no_readers_;
    int read_cnt_ = 0;
    bool write_ = false;

    void End() {
        mutex_.lock();
        --read_cnt_;
        no_readers_.notify_all();
        mutex_.unlock();
    }
};

Aucun commentaire:

Enregistrer un commentaire