2017-10-05 88 views
2

这是一个非常简单的例子,所以请多多包涵了一会儿....为什么我的代码会中断一个线程泄漏?

#include <boost/thread/thread.hpp> 
struct foo { 
    boost::thread t; 
    void do_something() { std::cout << "foo\n"; } 

    void thread_fun(){ 
     try { 
      boost::this_thread::sleep(boost::posix_time::seconds(2)); 
      { 
       boost::this_thread::disable_interruption di; 
       do_something(); 
      } 
     } catch (boost::thread_interrupted& e) {} 
    } 
    void interrupt_and_restart() { 
     t.interrupt(); 
     //if (t.joinable()) t.join(); // X 
     t = boost::thread(&foo::thread_fun,this);   
    } 
}; 

int main(){ 
    foo f; 
    for (int i=0;i<1000;i++){ 
     f.interrupt_and_restart(); 
     boost::this_thread::sleep(boost::posix_time::seconds(3)); 
    } 
} 

当我在Linux上运行的代码,并期待在内存消耗与top我看到在虚拟持续增加内存使用(和我的实际代码崩溃在某个时刻)。只有在中断它之后加入线程,内存使用率才会保持不变。这是为什么?

+2

所有的线程都需要一些内存来记帐(比如存储* real *线程函数的返回值)。如果你不“加入”这个线程,那么这个内存永远不会被回收。 –

+0

@Someprogrammerdude出于某种原因,我的印象是,如果线程用'thread_fun'完成,它会干净地终止我是否加入它。我已经知道这是错误的,但不完全明白它 – user463035818

+0

@Someprogrammerdude offtopic这个问题:我也观察到,这个特定的线程(我的意思是在真正的代码中的一个,但它看起来很相似),我的惊喜使用更多内存比我的系统中的任何其他线程,我知道的唯一区别是我打断它,但这将是一个完全不同的问题... – user463035818

回答

1

您没有加入线程:因此,需要一些资源来跟踪线程保持分配状态。

未加入的线程仍使用一些系统资源,即使它已被终止(例如其线程ID仍然有效)。此外,系统可能会对同时分配的线程数量施加限制,而未加入的线程则会计入该限制。 在我的Linux VM上使用cat /proc/sys/kernel/threads-max会给我23207个线程。

当你销毁一个可连接的线程对象时,最新版本的boost实际上应该会崩溃,而旧版本则很乐意遵守销毁请求。