C 11 线程安全队列:条件变量使用的混乱
在您的代码中,您使用互斥锁实现了线程安全队列和一个条件变量。但是,您在条件变量控制的代码块中偶尔会遇到段错误。具体来说,您注意到当队列为空时会发生段错误,这似乎违反直觉,因为条件变量旨在表示队列中新项目的可用性。
条件变量用法不正确
您的误解源于条件变量的错误使用。条件变量的目的是发出共享状态更改的信号,然后其他线程可以对此更改做出反应。但是,在您的代码中,您使用条件变量来等待特定条件(队列为空)变为 false。这是不正确的,因为当条件变为假(即队列不再为空)时,线程将唤醒,但不能保证条件保持为假(即队列可能同时再次变空) .
正确的条件变量用法
使用条件变量的正确方法是有一个循环来检查条件(在本例中,队列是否为空),如果条件不满足则进入等待状态。当条件发出信号时,线程将唤醒,但它会在继续之前立即重新检查条件。这确保了线程仅在唤醒时条件仍然为真时才执行所需的操作。
替代实现
这里是线程安全的替代实现解决该问题的队列:
<code class="cpp">template <class T> class SafeQueue { public: SafeQueue() : q(), m(), cv() {} void enqueue(T t) { std::lock_guard<std::mutex> lock(m); q.push(t); cv.notify_one(); } T dequeue() { std::unique_lock<std::mutex> lock(m); while (q.empty()) cv.wait(lock); T val = q.front(); q.pop(); return val; } private: std::queue<T> q; mutable std::mutex m; std::condition_variable cv; };</code>
在此实现中,正确使用条件变量来等待队列为空(或对于入队方法为非空)的条件变为 false。如果唤醒后队列非空,线程只会执行所需的操作(使项目出列)。
以上是为什么在 C 中使用条件变量检查空队列时会出现段错误?的详细内容。更多信息请关注PHP中文网其他相关文章!