Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

condition_variable, mutex and flag in one struct

Is to ok to combine all three variables into one struct?

struct lock_struct
{
    std::mutex mutex;
    std::conditional_variable cv;
    bool flag;
};

Are there any hidden synchronization problems with this approach? I do not intend to modify struct itself, only it's fields.

By the way, should I use bool or std::atomic<bool> when dealing with std::condition_variable's flag?

Edit: implemented it based on the answers.

class ConditionLock
{
public:
    void wait();
    void notify();
    bool getFlag() const;
private:
    mutable std::mutex _mutex;
    std::condition_variable _cv;
    bool flag;
};

void ConditionLock::wait()
{
    std::unique_lock<std::mutex> lock(_mutex);
    _cv.wait(lock, [&] { return flag; });
}

void ConditionLock::notify()
{
    std::unique_lock<std::mutex> lock(_mutex);
    flag = true;
    lock.unlock();
    _cv.notify_all();
}

bool ConditionLock::getFlag() const
{
    std::lock_guard<std::mutex> lock(_mutex);
    return flag;
}

I hope it's a correct implementation.

like image 837
CorellianAle Avatar asked Dec 04 '17 10:12

CorellianAle


1 Answers

Is to ok to combine all three variables into one struct?

Yes.

Are there any hidden synchronization problems with this approach?

Structure definition does not describe or enforce its intended usage. Since all the members are publicly accessible nothing prevents from incorrect or unintended usage.

A safer definition is make it a class with no public data members but public member functions.

By the way, should I use bool or std::atomic<bool> when dealing with std::condition_variable's flag

bool is enough as long as accessing that bool happens only when the mutex is locked. You can enforce this by making it a class with no public data members.

Note that if you make it std::atomic<bool> and modify it and signal the condition variable without locking the mutex, that leads to a race condition that causes the notifications from the condition variable to be lost, e.g.:

Thread 1             |  Thread 2
                     |  check the bool
modify the bool      |
signal the condition |  <notification not received>
                     |  wait on the codition
like image 179
Maxim Egorushkin Avatar answered Sep 28 '22 07:09

Maxim Egorushkin