Creating a lock that preserves the order of locking attempts in C++11

前端 未结 3 1916
南笙
南笙 2020-12-08 16:58

Is there a way to ensure that blocked threads get woken up in the same order as they got blocked? I read somewhere that this would be called a \"strong lock\" but I found no

3条回答
  •  北海茫月
    2020-12-08 17:14

    I tried Chris Dodd solution https://stackoverflow.com/a/14792685/4834897

    but the compiler returned errors because queues allows only standard containers that are capable. while references (&) are not copyable as you can see in the following answer by Akira Takahashi : https://stackoverflow.com/a/10475855/4834897

    so I corrected the solution using reference_wrapper which allows copyable references.

    EDIT: @Parvez Shaikh suggested small alteration to make the code more readable by moving cvar.pop() after signal.wait() in lock() function

    #include 
    #include 
    #include 
    #include 
    #include 
    
    #include  // std::reference_wrapper, std::ref
    
    using namespace std;
    
    class ordered_lock {
        queue> cvar;
        mutex                                        cvar_lock;
        bool                                         locked;
    public:
        ordered_lock() : locked(false) {}
        void lock() {
            unique_lock acquire(cvar_lock);
            if (locked) {
                condition_variable signal;
                cvar.emplace(std::ref(signal));
                signal.wait(acquire);
                cvar.pop();
            } else {
                locked = true;
            }
        }
        void unlock() {
            unique_lock acquire(cvar_lock);
            if (cvar.empty()) {
                locked = false;
            } else {
                cvar.front().get().notify_one();
            }
        }
    };
    

    Another option is to use pointers instead of references, but it seems less safe.

提交回复
热议问题