代码之家  ›  专栏  ›  技术社区  ›  ronag

如果我不加入发布版本中“破坏”的线程呢?

  •  0
  • ronag  · 技术社区  · 14 年前

    在许多情况下,我有一些类的行为类似于活动对象(有一个线程)。为了避免访问冲突,我总是要等待加入析构函数。这通常不是问题。

    然而,想象一个版本构建中有一些bug(死锁、LiveLock等)会导致 join() 不按时或根本不返回,这将导致整个应用程序在等待不再使用的对象时变得不起作用。如果这种情况发生在客户身上,就会成为一个问题。

    我宁愿被这个问题通知并跳过加入。泄漏线程和它的资源。

    跳过连接可以通过这样的方式实现。

       class MyActiveObject
        {
        public:
            MyActiveObject();
            ~MyActiveObject(){}
        private
            struct Implementation;
            std::shared_ptr<Implementation> pImpl_;
        };
    
        struct MyActiveObject::Implementation : std::enable_shared_from_this<Implementation >
        {
            Implementation() : thread_([=]{Run();})
            {
            }
    
            ~Implementation()
            {
                #ifdef _DEBUG
                    thread_.join();
                #else
                    if(!thread_.timed_join(SOME_TIMEOUT))
                        ALERT_SOME_HOW();
                #endif
            }
    
            void Dispose()
            {
                isRunning_ = false;
            }
    
            void Run()
            {
            #ifndef _DEBUG
                auto pKeepAlive = shared_from_this(); // Won't be destroyed until thread finishes
            #endif   
                isRunning_ = true;
                while(isRunning_)
                {
                     /* ... */
                }
            }
    
            boost::thread thread_;
            tbb::atomic<bool> isRunning_;
        };
    
    MyActiveObject::MyActiveObject() : pImpl_(new Implementation()){}
    MyActiveObject::~MyActiveObject() { pImpl_->Dispose(); }
    

    这是个好主意吗?还是有更好的策略?

    3 回复  |  直到 14 年前
        1
  •  1
  •   Potatoswatter    14 年前

    如果可行的话,最好激活某种结构分析,找出循环并打破死锁。

    它可能会错过一些破坏上的死锁,但同样,它也可能适用于捕获该上下文之外的死锁。

        2
  •  3
  •   Hans Passant    14 年前

    奇怪的问题:“如果我的代码中有错误,我会遇到问题。”嗯,是的。解决这个问题,不要试图把它写下来。这种纸只会产生两个错误,因为在你知道第一个错误是什么之前,你不能测试它。

        3
  •  1
  •   morechilli    14 年前

    如果您正在编写一个客户机应用程序,并且在此销毁序列之后应用程序的生命周期很短,那么它似乎是一个合理的实用解决方案。我建议您添加一些日志记录,并尝试收集发布日志(至少从内部测试中)。

    如果您正在编写一个服务器应用程序,并且这种破坏不是在服务器关闭期间进行的,那么我将不鼓励这种行为,因为您的服务器经常耗尽资源不太可能是好的。

    在这两种情况下,开发团队都应该高度重视任何已知的死锁问题,即使这种影响对客户来说是隐藏的。