为什么 std::condition_variable wait() 需要 std::unique_lock arg?

发布于 2025-01-11 01:00:31 字数 546 浏览 0 评论 0原文

我的线程不需要被锁定。 std::unique_lock 在构造时锁定线程。我只是使用 cond_var.wait() 作为避免繁忙等待的方法。我基本上通过将 unique_lock 放在一个很小的范围内来规避自动锁定,从而在它离开这个小范围后销毁唯一锁。此外,如果相关的话,只有一个消费者线程

{
std::unique_lock<std::mutex> dispatch_ul(dispatch_mtx);
pq_cond.wait(dispatch_ul);
}

是否有更好的选择来避免 unique_lock 不必要的自动锁定功能?我正在寻找一个无互斥选项来简单地向线程发出信号,我知道 std:: condition_variable_any 但这需要某种互斥体,这在我的情况下又是不必要的。

My thread does not need to be locked. std::unique_lock locks thread on construction. I am simply using cond_var.wait() as a way to avoid busy waiting. I have essentially circumvented the auto-locking by putting the unique_lock within a tiny scope and hence destroying the unique lock after it leaves the tiny scope. Additionally, there is only a single consumer thread if that's relevant.

{
std::unique_lock<std::mutex> dispatch_ul(dispatch_mtx);
pq_cond.wait(dispatch_ul);
}

Is there possibly a better option to avoid the unnecessary auto-lock functionality from the unique_lock? I'm looking for a mutexless option to simply signal the thread, I am aware of std::condition_variable_any but that requires a mutex of sorts which is yet again unnessesary in my case.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

伤感在游骋 2025-01-18 01:00:31

你需要一个锁来防止这种常见的新手错误:

  1. 生产者线程生产一些东西,
  2. 生产者线程调用 some_condition.notify_all(),
  3. 生产者线程空闲一段时间,

同时:

  1. 消费者线程调用 some_condition。 wait(...)
  2. 消费者线程等待,...
  3. 并且等待,...
  4. 并且等待。

条件变量不是标志。它不记得它已被通知。如果生产者在消费者进入 wait() 调用之前调用 notify_one()notify_all(),那么通知就“丢失”了。

为了防止丢失通知,必须有一些共享数据告诉消费者是否需要等待,并且必须有一个锁来保护共享数据。

生产者应该:

  1. 锁定锁,
  2. 更新共享数据,
  3. 通知条件变量,
  4. 释放锁

消费者必须:

  1. 锁定锁,
  2. 检查共享数据是否需要等待,
  3. 如果需要,
  4. 消耗任何东西,
  5. 释放锁。

消费者需要将锁传递给 wait(...) 调用,以便 wait(...) 可以暂时解锁它,然后重新锁定它返回之前。如果 wait(...) 没有解锁锁,那么生产者将永远无法到达 notify() 调用。

You need a lock to prevent this common newbie mistake:

  1. Producer thread produces something,
  2. Producer thread calls some_condition.notify_all(),
  3. Producer thread goes idle for a while,

meanwhile:

  1. Consumer thread calls some_condition.wait(...)
  2. Consumer thread waits,...
  3. And waits,...
  4. And waits.

A condition variable is not a flag. It does not remember that it was notified. If the producer calls notify_one() or notify_all() before the consumer has entered the wait() call, then the notification is "lost."

In order to prevent lost notifications, there must be some shared data that tells the consumer whether or not it needs to wait, and there must be a lock to protect the shared data.

The producer should:

  1. Lock the lock,
  2. update the shared data,
  3. notify the condition variable,
  4. release the lock

The consumer must then:

  1. Lock the lock,
  2. Check the shared data to see if it needs wait,
  3. Wait if needed,
  4. consume whatever,
  5. release the lock.

The consumer needs to pass the lock in to the wait(...) call so that wait(...) can temporarily unlock it, and then re-lock it before returning. If wait(...) did not unlock the lock, then the producer would never be able to reach the notify() call.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文