首先是我的代码,让我的解释更清楚:
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 thewait
. This relaxes the usual rules, which would have required allwait
calls to happen before destruction. Only the notification to unblock thewait
must happen before destruction.
基本上 wait
函数需要以原子方式执行锁定和等待:
The execution of
notify_one
andnotify_all
shall be atomic. The execution ofwait
,wait_for
, andwait_until
shall be performed in three atomic parts:
- the release of the mutex and entry into the waiting state;
- the unblocking of the
wait
; and- the reacquisition of the lock.
一旦 notify
唤醒一个线程,它就应该被认为是“未阻塞的”并且应该争夺互斥量。
关于 std::mutex
也有类似的保证:线程不需要在 mutex 被销毁之前离开 unlock
。
引用自 C++ 标准:
The implementation shall provide
lock
andunlock
operations, as described below. For purposes of determining the existence of a data race, these behave as atomic operations. Thelock
andunlock
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 itsunlock
call.
这样的保证是为了避免像 this 这样的问题。 ,当对象内部的互斥量用于保护对象引用计数器时。
请注意,这并不能保证您的实现在这方面没有错误。过去 glibc 有多个与同步对象破坏相关的错误,特别是 pthread_mutex_unlock
是 accessing mutex before returning .
关于c++ - 等待时销毁 condition_variable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52298859/