What I am looking for is something like the wait_queue_t in linux kernel. My underlying data structure related to the synchronization is lockfree thus does not need protection of a mutex.
Having to acquire std::mutex
just to be able to use std::condition_variable
for blocking wait seems to introduce unnecessary overhead.
I know there is futex
for linux and WaitOnAddress
for Windows but I am more interested in language standard stuff here.
According to cppreference wiki std::condition_variable_any
can work with any custom Lockable
.
So what if I use it with a dummy fake lock like the following:
class FakeLock
{
public:
inline void lock() {}
inline void unlock() {}
inline bool try_lock() { return true; }
};
template<typename WaitLock=FakeLock>
class WaitQueue
{
private:
WaitLock m_lock;
std::condition_variable_any m_cond;
public:
inline void wait()
{
std::unique_lock<WaitLock> lock(m_lock);
m_cond.wait(lock);
}
inline void notify_one()
{
m_cond.notify_one();
}
inline void notify_all()
{
m_cond.notify_all();
}
};
Is there any potential risk of unexpected behavior to use the WaitQueue
above in the way linux kernel wait_queue_t
is used?
Thinking about the problem again I think I got an answer.
Given a class LockFreeStack
which is a lockfree stack.
consider the following code:
WaitQueue wq;
LockFreeStack<std::string> stack;
std::thread t1([&]() {
while (true) {
// sleep for some time
stack.push(/* random string */); // (1.1)
wq.notify_one(); // (1.2)
}
});
std::thread t2([&]() {
while (true) {
if (stack.empty()) // (2.1)
wq.wait(); // (2.2)
auto str = stack.pop();
// print string
}
});
Without guarding wait_queue / conditional variable with a real lock, it is possible for the two threads to execute in the following sequence:
(2.1)
(1.1)
(1.2)
(2.2)
Making thread t2
perfectly miss the latest update from t1
. t2
will only be able to resume execution after the next notify_one()
call.
A real lock is necessary to guarantee that the conditional variable is changed atomically with the actual data/state of interest.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.