声明:既不升压,也不C ++ 11允许的。
我有一个程序,我在其中创建的实例Foo
,我与它在多个线程运行。 然后我想删除它安全地使这些线程不属于分段错误。
我添加了一个互斥体成员Foo
每个线程函数运行时间将其锁定。 为了不同的线程不会互相冲突。
class Foo
{
public:
pthread_mutex_t mutex;
};
void* thread ( void* fooPtr )
{
Foo* fooPointer = (Foo*) fooPtr;
while ( 1 )
{
if ( fooPointer )
{
pthread_mutex_lock ( &fooPointer->mutex );
/* some code, involving fooPointer */
pthread_mutex_unlock ( &fooPointer->mutex );
}
else
{
pthread_exit ( NULL );
}
}
}
现在我想删除foo
所以发生在线程没有错误安全。 我添加了一个析构函数Foo
:
Foo::~Foo()
{
pthread_mutex_lock ( &mutex );
}
现在对象将不会被删除,直到所有线程完成电流回路。
现在的问题是:将互斥的实例被删除后可以解锁? 一个实例被删除后,所有的线程将结束? 我敢打赌,答案是no
。 所以我改变了析构函数,但现在看来,线程安全的:
Foo::~Foo()
{
pthread_mutex_lock ( &mutex );
pthread_mutex_unlock ( &mutex );
}
线程函数可以锁定互斥锁,并开始工作后的实例pthread_mutex_unlock ( &mutex );
和对象之前被删除?
现在缺少的是在这里完成时线程处理该规定的条件。 特定对象实例的删除是不是一个很好的条件。 您还没有该对象被删除告诉我们。 如果我们能看到这个代码,多余的背景下将是有益的。
我的建议是,而不是删除对象,设置(例如布尔活跃())在对象上的标志。 此标志将然后由所有线程进行检查,并在表示停止处理,那么线程将停止。 设置此标志,你正在删除Foo对象。 然后,一旦所有线程都停止,删除Foo对象。
如果删除的对象,并希望能够收购其互斥锁,你可能会得到一个崩溃,或者至少不稳定的行为,因为互斥是美孚的成员,它将与对象被销毁。
下面是我的意思的例子:
class Foo
{
public:
void lockMutex();
void unlockMutex();
// Active should be mutex protected as well
// Or you could consider using a pthread_rwlock
bool active() {return active_;}
void setActive(bool a) {active_ = a;}
private:
pthread_mutex_t mutex;
bool active_;
};
void* thread ( void* fooPtr )
{
Foo* fooPointer = (Foo*) fooPtr;
while ( 1 )
{
if ( fooPointer->active() )
{
fooPointer->lockMutex();
/* some code, involving fooPointer */
fooPointer->unlockMutex();
}
else
{
pthread_exit ( NULL );
}
}
// somewhere else in the code
fooPointer->setActive(false);
}
富:: SETACTIVE(真)必须被调用无论是在构造函数中,或创建对象时。 而且一旦线程停止Foo对象应该被删除,在pthread_join后,最有可能的()已完成。
让我们先从开始你的问题:
我有一个程序,我在其中创建富的一个实例,我用它在多个线程运行。 然后我想删除它安全地使这些线程不属于分段错误。
您不能删除的对象,它是在使用中。 互斥再多就会解决这个问题。
我添加了一个析构函数的Foo
当这是只运行Foo
被删除。 其内容也没有多大关系,但:这是错误的,而其他线程还在使用美孚调用析构函数。
我想,当一个实例被删除线程安全地退出。 这怎么可能?
嗯,这是正确的问题。 我可以写一大堆供您使用代码,但这些代码将只是一个副本boost::weak_ptr
。 所以,我不会理会。 就拿升压代码自己。
升压不允许的。
那么,为什么你要问在计算器上? 这是本质相同的许可证。
你的代码贴是不正确的,因为被破坏的步骤C ++对象吹:
obj->Foo::~Foo();
free memory //maybe delete if allocated by new
所以你的源仅protoecting析构函数而不是记忆中解脱出来。
也许源代码如下可以帮助你,这是简单粗暴,但我认为它可以工作
class Foo
{
public:
void dosomething() {}
};
template<typename T>
class Protect
{
public:
struct auto_lock {
auto_lock(pthread_mutex_t& mutex)
: _mutex(mutex)
{
pthread_mutex_lock ( &_mutex );
}
~ auto_lock()
{
pthread_mutex_unlock ( &_mutex );
}
pthread_mutex_t& _mutex;
};
Protect(T*& p): _p(p) {}
T* get() { return _p; }
void lock() { pthread_mutex_lock ( &_mutex ); }
void unlock() { pthread_mutex_unlock ( &_mutex );}
pthread_mutex_t& getlock() { return _mutex; }
void safe_release() {
auto_lock l(_mutex);
if (_p != NULL) {
delete _p;
_p = NULL;
}
}
private:
T*& _p;
pthread_mutex_t _mutex;
};
void* thread ( void* proPtr )
{
Protect<Foo>* proPointer = (Protect<Foo>*) proPtr;
while ( 1 )
{
Protect<Foo>::auto_lock l(proPointer->getlock());
Foo* fooPtr = proPointer->get();
if ( fooPtr )
{
fooPtr->dosomething();
}
else
{
pthread_exit ( NULL );
}
}
}