简体   繁体   English

在析构函数中加入boost :: thread实例

[英]Joining a boost::thread instance in the destructor

I'm seeing an issue where a call to boost's thread->join in a destructor leads to a deadlock. 我看到一个问题,在析构函数中调用boost的thread-> join会导致死锁。 I don't understand why, and I'm not too keen on keeping code that just works (and I don't understand why it does) in the project. 我不明白为什么,而且我不太热衷于保持代码在项目中正常工作(我不明白为什么会这样)。

Class declaration (I've stripped the run() method of try/catch for brevity: according to the boost thread documentation, the result should be the same with or without it): 类声明(我为了简洁而剥离了try / catch的run()方法:根据boost线程文档,结果应该是相同的,有或没有):

class B 
{
public:
    void operator()(){run();}
    void run();
    void shutdown();
    ~B();
    B();
    boost::thread *thr;
    bool shutdown_requested;
};

void B::shutdown()
{
    shutdown_requested = true;

    if (thr != NULL)
    {
        thr->interrupt();
        thr->join(); // deadlock occurs here!
        delete thr;
        thr = NULL;
    }
}

B::~B()
{
    shutdown();
}

B::B()
{
    thr = new boost::thread(boost::ref(*this));
}

void B::run()
{
    while (!shutdown_requested)
    {
        boost::xtime xt;
        boost::xtime_get(&xt, boost::TIME_UTC);
        xt.sec += 30;
        boost::this_thread::sleep(xt);
    }
}

Snippet which does not work: 片段不起作用:

int main()
{
    B *b = new B;

    Sleep(5000);
    printf("deleting \n");fflush(stdout);
//    b->shutdown();
    delete b;
    printf("done\n");fflush(stdout);

    return 0;
}

Snippet which works: 工作的片段:

int main()
{
    B *b = new B;

    Sleep(5000);
    printf("deleting \n");fflush(stdout);
    b->shutdown();
    delete b;
    printf("done\n");fflush(stdout);

    return 0;
}

I think the reason for this behavior has something to do with this snippet of the boost documentation: 我认为这种行为的原因与boost文档的这个片段有关:

the user of Boost.Thread must ensure that the referred-to object outlives the newly-created thread of execution. Boost.Thread的用户必须确保引用的对象超过新创建的执行线程。

But I don't really understand why the deadlock - joining the thread would not call the destructor on B and the object itself is not deleted when the run() method is supposed to exit. 但我真的不明白为什么死锁 - 加入线程不会调用B上的析构函数,并且当run()方法应该退出时,对象本身不会被删除。

I've found the issue: it boils down to an over-zealous programmer. 我发现了这个问题:它归结为一个过度狂热的程序员。

I had originally compiled my project using DUMA ( http://sourceforge.net/projects/duma/ ) to see if my implementation of the current module was leak-free. 我最初使用DUMA( http://sourceforge.net/projects/duma/ )编译了我的项目,看看我当前模块的实现是否是无泄漏的。 Unfortunately, my test sandbox also had the duma settings on, which I did not realize until I stepped through the code in a debugger. 不幸的是,我的测试沙箱也有duma设置,直到我在调试器中执行代码之前我才意识到这一点。

After removing all memory leak-detection, everything works as expected. 删除所有内存泄漏检测后,一切都按预期工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用析构函数进行线程连接 - Thread joining using a destructor 提升线程析构函数未定义的符号 - Boost Thread Destructor Undefined Symbol static 分析工具警告析构函数中的 boost thread::join() - boost thread::join() in a destructor is warned by a static analysis tool 如何处理:如果 boost::asio::post 无休止地重复,当 boost::asio::thread_pool 析构函数被触发时? - How to deal: if boost::asio::post is endlessly repeated, when boost::asio::thread_pool destructor is triggered? 静态boost :: wregex实例是否是线程安全的? - Is a static boost::wregex instance thread-safe? 为什么 boost::thread 的析构函数会分离可连接线程,而不是按照标准建议调用 terminate()? - Why is destructor of boost::thread detaching joinable thread instead of calling terminate() as standard suggests? 加入成员线程访问父析构函数中其父类的其他成员会导致未定义的行为吗? - Does joining a member thread accessing other members of its parent class in the parent's destructor result in undefined behavior? Boost 日志析构函数中止 - Boost log destructor aborted boost ::任何析构函数崩溃 - boost::any destructor crash 新的boost :: thread导致对象析构函数被调用的次数超过预期? - New boost::thread causes object destructor to be called many times more than expected?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM