由于我已经开始制作一个旨在获得跨平台支持的小项目,我选择了boost 1.47来与底层操作系统进行交互。我的项目需要一些多线程,所以我在boost线程上做了一个小包装来满足我的需求。
我知道的很少,在破坏对象(?)之后,boost显然会将线程留在内存中,或者它可能会有某种内存泄漏的可能性。
我的包装器的实现有一个类型为thread的scoped_ptr,当一个调用包装类中的start()函数时,scoped ptr将被初始化。使用thread-> interrupt()从主线程停止正在运行的线程,并从包装函数调用析构函数。 (线程的过程结构的析构函数,其中包含operator()()。
这是包装类的实现: (注意:i_exception和其他几个函数是其他项目组件的一部分)
#define TIMED_JOIN boost::posix_time::milliseconds(1)
namespace utils
{
struct thread_threadable
{
template<typename T> friend class ut_thread;
private:
boost::shared_ptr<thread_threadable> instance;
public:
virtual ~thread_threadable() {}
virtual void operator()() = 0;
};
template<typename T = thread_threadable>
class ut_thread
{
public:
typedef T proc_t;
private:
boost::scoped_ptr<boost::thread> thr;
boost::shared_ptr<proc_t> proc;
public:
explicit ut_thread(const boost::shared_ptr<proc_t> &procedure) : proc(procedure) {}
~ut_thread();
void start();
void stop();
bool running() const {return this->thr.get() != NULL;}
proc_t &procedure() const
{
BOOST_ASSERT(this->proc.get() != NULL);
return *this->proc;
}
};
}
typedef utils::thread_threadable threadable;
template<typename T>
utils::ut_thread<T>::~ut_thread()
{
if(this->thr.get() != NULL)
{
BOOST_ASSERT(this->proc.get() != NULL);
this->stop();
}
}
template<typename T>
void utils::ut_thread<T>::start()
{
if(this->thr.get() != NULL)
i_exception::throw_this("another thread of this procedure is already running");
if(this->proc.get() == NULL)
i_exception::throw_this("procedure object not initialized");
this->proc->instance = this->proc;
this->thr.reset(new boost::thread(boost::ref(*this->proc)));
this->thr->timed_join(TIMED_JOIN);
}
template<typename T>
void utils::ut_thread<T>::stop()
{
if(this->thr.get() == NULL)
i_exception::throw_this("no thread was running");
this->thr->interrupt();
this->proc->~T();
this->thr.reset(NULL);
}
然后通过检查这个包装类的功能,我对main.cpp进行了测试:
struct my_thr : public utils::thread_threadable
{
void operator()()
{
while(true);
}
};
int main()
{
while(true)
{
utils::ut_thread<> thr(boost::shared_ptr<threadable>(new my_thr));
utils::ut_thread<> thr1(boost::shared_ptr<threadable>(new my_thr));
thr.start();
thr1.start();
boost::this_thread::sleep(boost::posix_time::seconds(1));
}
return 0;
}
此时我注意到这些线程没有被破坏,它们将保留在内存中,直到程序终止。他们还继续执行'while(true)'语句。
所以我问,这会导致什么样的行为?是定义了什么,还是只是一个bug或其他东西?
答案 0 :(得分:3)
首先interrupt
只会停止特定ìnterruption points
的帖子(取自boost::threads
文档,稍加重新格式化):
预定义中断点
以下功能是中断点,将抛出 如果为当前启用中断,则boost :: thread_interrupted 线程,并为当前线程请求中断:
boost::thread::join() boost::thread::timed_join() boost::condition_variable::wait() boost::condition_variable::timed_wait() boost::condition_variable_any::wait() boost::condition_variable_any::timed_wait() boost::thread::sleep() boost::this_thread::sleep() boost::this_thread::interruption_point()
由于你的线程执行中没有任何一个调用它interrupt()
应该没有效果。
现在要销毁thread
:
〜螺纹();
效果:如果*这有一个关联的执行线程,则调用detach()。摧毁*这个。
投掷:没什么。
你调用线程的timed_join()
应该失败,因为线程不会快速完成它的执行。因此,您没有join
(或detach
,但这不会改变最终结果)您的线程,这意味着它们确实具有关联的执行线程销毁。因此它们是分离的,意味着它们将一直运行直到它们完成,即使它们不再通过boost::thread
对象可控制。由于它们正在执行并且无限循环,因此完成它们的执行可能需要一些时间来说。
作为旁注:如果您稍后选择更改为C ++ 11 std::threads
,则应注意,在未手动调用join()
或detach()
的情况下销毁这些代码不是有效代码。< / p>