Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如果我没有';t在“上连接螺纹”;“销毁”;在发布版本中?_C++_Multithreading_Boost_Boost Thread - Fatal编程技术网

C++ 如果我没有';t在“上连接螺纹”;“销毁”;在发布版本中?

C++ 如果我没有';t在“上连接螺纹”;“销毁”;在发布版本中?,c++,multithreading,boost,boost-thread,C++,Multithreading,Boost,Boost Thread,在许多情况下,我的类的行为类似于活动对象(有一个线程)。为了避免访问冲突,我总是要等待析构函数中的join。这通常不是问题 但是,想象一下,一个发布版本有一些bug(死锁、活锁等),导致join()无法按时返回,或者根本无法返回,这将导致整个应用程序在等待不再使用的对象时变得不起作用。如果这种情况发生在客户身上,则会成为一个问题 我宁愿被问题通知而跳过加入。泄漏线程和它的资源 跳过连接可以通过以下方式实现 class MyActiveObject { public:

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

但是,想象一下,一个发布版本有一些bug(死锁、活锁等),导致
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(); }
类MyActiveObject
{
公众:
MyActiveObject();
~MyActiveObject(){}
私有的
结构实现;
std::共享的ptr pImpl;
};
struct MyActiveObject::实现:std::从\u中启用\u共享\u
{
实现():线程([=]{Run();})
{
}
~Implementation()
{
#ifdef_调试
螺纹连接();
#否则
如果(!线程超时连接(某些超时))
提醒你怎么做;
#恩迪夫
}
无效处置()
{
isRunning=假;
}
无效运行()
{
#ifndef\u调试
auto-pKeepAlive=shared_from_this();//在线程完成之前不会被销毁
#恩迪夫
isRunning=真;
同时(正在运行)
{
/* ... */
}
}
boost::thread-thread;
tbb::原子正在运行;
};
MyActiveObject::MyActiveObject():pImpl_389;(新实现()){}
MyActiveObject::~MyActiveObject(){pImpl->Dispose();}

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

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

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


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

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

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


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

如果可行,最好激活某种结构分析来找到循环并打破死锁


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

如果可行,最好激活某种结构分析,以找到循环并打破死锁


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

奇怪的问题:“如果我的代码中有错误,我就有问题了。”。嗯,是的。修复错误,不要试图掩盖它。这种论文只会产生两个bug,因为在知道第一个bug是什么之前,你无法测试它。

奇怪的问题:“如果我的代码中有bug,我就有问题了。”。嗯,是的。修复错误,不要试图掩盖它。这种纸只会产生两个bug,因为在你知道第一个bug是什么之前你无法测试它。

关于“某种结构分析”你愿意更详细一点吗?@ronag:如果你有两个线程对象没有终止并且彼此有明显的指针,你可以试着发现它并做些什么。这取决于很多。您是否愿意更详细地介绍一下“某种结构分析”?@ronag:如果您有两个线程对象没有终止,并且有明显的指向彼此的指针,您可以尝试检测它们并做一些事情。这取决于很多方面。+1-如果你的线程没有锁,你无论如何都会遇到问题。解决真正的问题我同意你的看法。还有一个问题是,某些类型的错误(特别是在谈论多线程时)在测试期间并不总是被检测到。好吧,不要做得太多,大声喊叫并崩溃,这样你就会知道。这种计时器正是开始喊叫所需的。@ronag:问题不在于测试期间是否检测到错误,但是,当它们发生时,无论您如何处理应用程序并将其覆盖,应用程序都无法正常工作。如果您有一个从未释放过的锁,那么无论您是否在线程上调用
join
,它都会造成严重破坏。+1-如果您的线程没有释放锁,那么您仍然会遇到问题。解决真正的问题我同意你的看法。还有一个问题是,某些类型的错误(特别是在谈论多线程时)在测试过程中并不总是被检测到。好吧,不要做得太多,大声叫喊并崩溃,这样你就会知道。这种计时器正是开始叫喊所需要的。@ronag:问题不在于测试过程中是否检测到错误,而是