gpt4 book ai didi

c++ - 将虚拟假锁与 std::condition_variable_any 一起使用是否安全?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:41:10 28 4
gpt4 key购买 nike

我正在寻找的是类似于 linux 内核中的 wait_queue_t 的东西。我与同步相关的底层数据结构是无锁的,因此不需要互斥锁的保护。

必须获取 std::mutex 才能使用 std::condition_variable 来阻塞等待,这似乎引入了不必要的开销。

我知道有用于 linux 的 futex 和用于 Windows 的 WaitOnAddress 但我对这里的语言标准内容更感兴趣。

根据 cppreference wiki std::condition_variable_any 可以与任何自定义 Lockable 一起使用。

如果我将它与如下所示的虚拟假锁一起使用会怎样:

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();
}
};

在使用 linux 内核 wait_queue_t 的方式中使用上面的 WaitQueue 是否存在意外行为的潜在风险?

最佳答案

再次思考这个问题我想我找到了答案。

给定一个类 LockFreeStack,它是一个无锁堆栈。

考虑以下代码:

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
}
});

如果没有用真正的锁保护 wait_queue/条件变量,两个线程有​​可能按以下顺序执行:

(2.1)
(1.1)
(1.2)
(2.2)

使线程 t2 完全错过 t1 的最新更新。 t2 将只能在下一次 notify_one() 调用后恢复执行。

一个真正的锁是必要的,以保证条件变量随着感兴趣的实际数据/状态自动改变。

关于c++ - 将虚拟假锁与 std::condition_variable_any 一起使用是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50165512/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com