c++ - 等待时销毁 condition_variable

标签 c++ multithreading c++11

首先是我的代码,让我的解释更清楚:

struct Foo {
    std::condition_variable cv;
};
static Foo* foo; // dynamically created object

// Thread1
foo->cv.wait(...);


// Thread2
foo->cv.notify();
delete foo; // thread1 might have not left the wait function yet

我正在尝试删除处于 wait 中的 std::condition_variable。所以根据我的理解,我必须先通知它让它离开等待例程,然后我才能删除它。但是在调用 notify* 之后我不能马上删除它,因为它可能还在等待,因为它需要几个周期。实现这一目标的常用方法是什么?

最佳答案

您可以立即删除它。

引用自 C++ 标准:

~ condition_variable();

Requires: There shall be no thread blocked on *this. [Note: That is, all threads shall have been notified; they may subsequently block on the lock specified in the wait. This relaxes the usual rules, which would have required all wait calls to happen before destruction. Only the notification to unblock the wait must happen before destruction.

基本上 wait 函数需要以原子方式执行锁定和等待:

The execution of notify_one and notify_all shall be atomic. The execution of wait, wait_for, and wait_until shall be performed in three atomic parts:

  1. the release of the mutex and entry into the waiting state;
  2. the unblocking of the wait; and
  3. the reacquisition of the lock.

一旦 notify 唤醒一个线程,它就应该被认为是“未阻塞的”并且应该争夺互斥量。


关于 std::mutex 也有类似的保证:线程不需要在 mutex 被销毁之前离开 unlock

引用自 C++ 标准:

The implementation shall provide lock and unlock operations, as described below. For purposes of determining the existence of a data race, these behave as atomic operations. The lock and unlock operations on a single mutex shall appear to occur in a single total order.

后来:

Note: After a thread A has called unlock(), releasing a mutex, it is possible for another thread B to lock the same mutex, observe that it is no longer in use, unlock it, and destroy it, before thread A appears to have returned from its unlock call.

这样的保证是为了避免像 this 这样的问题。 ,当对象内部的互斥量用于保护对象引用计数器时。


请注意,这并不能保证您的实现在这方面没有错误。过去 glibc 有多个与同步对象破坏相关的错误,特别是 pthread_mutex_unlockaccessing mutex before returning .

关于c++ - 等待时销毁 condition_variable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52298859/

相关文章:

c# - 关于C#事件调用中使用的线程

c++ - 右值引用和 auto&& 局部变量

c++ - 如何获得指向编译器选择的重载函数的函数指针?

c++ - 有使用英特尔线程构建模块的经验吗?

multithreading - 在Python中使用动态生成的MPI深度优先搜索

c++ - std::vector 在 push_back 期间多次调用析构函数?

c++ - 我无法使用 QFileDialog、C++ QT 保存 .txt 文件

c++ - 如何将 C++ 代码与 "libguile"和 "guile-1.8.8"链接起来?

c++ - 多次使用 strtok_s

c++ - 通过静态函数增加非静态变量