首页  >  文章  >  后端开发  >  为什么在 C 中使用条件变量检查空队列时会出现段错误?

为什么在 C 中使用条件变量检查空队列时会出现段错误?

Linda Hamilton
Linda Hamilton原创
2024-10-31 21:14:29655浏览

Why Am I Getting Segfaults When Using a Condition Variable to Check for an Empty Queue in C  ?

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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn