如何让线程等待对象的销毁
how to let a thread wait for destruction of an object
我想让一个线程等待另一个线程销毁特定对象。我想过以某种方式实现它,就像这样:
class Foo {
private:
pthread_mutex_t* mutex;
pthread_cond_t* condition;
public:
Foo(pthread_mutex_t* _mutex, pthread_cond_t* _condition) : mutex(_mutex), condition(_condition) {}
void waitForDestruction(void) {
pthread_mutex_lock(mutex);
pthread_cond_wait(condition,mutex);
pthread_mutex_unlock(mutex);
}
~Foo(void) {
pthread_mutex_lock(mutex);
pthread_cond_signal(condition);
pthread_mutex_unlock(mutex);
}
};
但是,我知道我必须在 waitForDestruction 方法中处理虚假唤醒,但我无法对"this"调用任何内容,因为它已经被破坏了。
我想到的另一种可能性是不使用条件变量,而是在构造函数中锁定互斥锁,在析构函数中解锁它并在 waitForDestruction 方法中锁定/解锁它 - 这应该适用于非递归互斥锁,iirc 我可以从未锁定它的线程解锁互斥锁,对吧?第二个选项会受到任何虚假唤醒的影响吗?
这总是一件困难的事情。但是这些代码行怎么样:
struct FooSync {
typedef boost::shared_ptr<FooSync> Ptr;
FooSync() : owner(boost::this_thread::get_id()) {
}
void Wait() {
assert(boost::this_thread::get_id() != owner);
mutex.lock();
mutex.unlock();
}
boost::mutex mutex;
boost::thread::id owner;
};
struct Foo {
Foo() { }
~Foo() {
for (size_t i = 0; i < waiters.size(); ++i) {
waiters[i]->mutex.unlock();
}
}
FooSync::Ptr GetSync() {
waiters.push_back(FooSync::Ptr(new FooSync));
waiters.back()->mutex.lock();
return waiters.back();
}
std::vector<FooSync::Ptr> waiters;
};
上面的解决方案将允许在单个Foo
对象上任意数量的销毁等待对象。只要它能正确管理这些对象占用的内存。似乎没有什么可以阻止在堆栈上创建Foo
实例。
虽然我看到的唯一缺点是它要求销毁等待对象始终在"拥有"对象实例Foo
线程中创建,否则可能会发生递归锁。还有更多,如果从多个线程调用GetSync
则在push_back
之后可能会出现争用条件。
<小时 />
编辑:
好的,我已经重新考虑了这个问题并提出了新的解决方案。看一看:
typedef boost::shared_ptr<boost::shared_mutex> MutexPtr;
struct FooSync {
typedef boost::shared_ptr<FooSync> Ptr;
FooSync(MutexPtr const& ptr) : mutex(ptr) {
}
void Wait() {
mutex->lock_shared();
mutex->unlock_shared();
}
MutexPtr mutex;
};
struct Foo {
Foo() : mutex(new boost::shared_mutex) {
mutex->lock();
}
~Foo() {
mutex->unlock();
}
FooSync::Ptr GetSync() {
return FooSync::Ptr(new FooSync(mutex));
}
MutexPtr mutex;
};
现在它看起来相当干净,更少的代码点受竞争条件的影响。对象本身和所有同步对象之间只有一个同步基元共享。必须采取一些努力来克服在对象本身所在的线程中调用Wait
的情况(如我的第一个示例)。如果目标平台不支持shared_mutex
则可以使用好的mutex
。 shared_mutex
似乎减轻了锁的负担,因为有很多FooSync
在等待。
相关文章:
- USB-HID 读/写(重叠)等待单个对象不返回C++
- 如何让线程等待对象完全破坏?(对象也有一个线程)?
- 避免并发等待对象中的死锁
- 有没有办法调试排队等待对象的Qt插槽调用
- 执行 commaind "systeminfo"后,等待单个对象停止
- 在返回之前等待输出的自定义QProcess对象
- 你真的能用WaitFor..等待条件变量吗..对象
- 我可以在 QP(量子平台)活动对象中等待 Windows 事件(WaitForMultipleObjects)吗?
- 如何让线程等待对象的销毁
- 等待单个对象不超时
- 同步对象以等待而不阻止C++中的 UI(C++生成器)
- 等待多个对象无法正常工作
- 如何在进程之间共享内核对象,例如可等待计时器
- 简单的多线程帮助?C++、等待单一对象和同步
- 如何终止等待对象的辅助线程
- Q等待条件,手动复位除外?(或者在Qt Concurrent之外创建QFuture对象?)
- 如何构造用于等待来自不相关类的两个信号对象的代码
- 为什么condition_variable没有等待函数,它不重新锁定互斥对象
- 等待只给定已创建的进程向量的多个对象
- 将等待多个对象修改*多个*对象的状态