Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.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++ 当我希望线程终止时,删除包含运行线程的类是否可以/安全?_C++_C++11_Stdthread - Fatal编程技术网

C++ 当我希望线程终止时,删除包含运行线程的类是否可以/安全?

C++ 当我希望线程终止时,删除包含运行线程的类是否可以/安全?,c++,c++11,stdthread,C++,C++11,Stdthread,下面是一个简单的例子: class worker { std::thread thread1; std::thread thread2; worker(){} start() { thread1 = std::thread([]() { std::this_thread::sleep_for(std::chrono::milliseconds(50000)); });

下面是一个简单的例子:

class worker
{
    std::thread thread1;
    std::thread thread2;

    worker(){}

    start()
    {
        thread1 = std::thread([]()
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(50000));
        });
        thread1.deteach();

        thread2 = std::thread([]()
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(50000));
        });
        thread2.deteach();
    }

    ~worker()
    {
        // Ignore this part! - as per Richard's comment :)
        //thread1.join();   // <-- do I need this at all?
        //thread2.join();   // <-- do I need this at all?
    }
}

int main()
{
    worker *p_worker = new worker();
    p_worker->start();
    std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // 1 sec

    delete p_worker;
}
类工作者
{
标准:螺纹1;
标准:螺纹2;
工作者(){}
开始()
{
thread1=std::thread([])()
{
std::this_线程::sleep_for(std::chrono::毫秒(50000));
});
thread1.detach();
thread2=std::thread([])()
{
std::this_线程::sleep_for(std::chrono::毫秒(50000));
});
螺纹2.detach();
}
~worker()
{
//忽略这部分!-根据Richard的评论:)

//thread1.join();//是的,线程被
std::thread
dtor完全破坏,如果它们仍然可以连接(正在运行且未分离)


一般来说,仅仅终止是为了避免意外状态造成的进一步损害,或者如果应用程序是在该点构建的无害终止。

如注释中所述,您不能加入分离的线程。 分离的线程意味着独立运行。一般来说,分离类所拥有的线程是个坏主意

我建议使用布尔值来控制线程的生命周期

例如,您可以这样做:

class worker
{
private:
    std::thread thread1;
    std::atomic<bool> thread1ShouldRun;
    std::thread thread2;
    std::atomic<bool> thread2ShouldRun;

    void workerFunc1() {
        bool threadWorkIsDone = false;
        while (thread1ShouldRun.load()) {
            // Do Stuff
            // Set threadXShouldRun to false when you're done
            // thread1ShouldRun.store(false);
        }
    }

    void workerFunc2() {
        bool threadWorkIsDone = false;
        while (thread2ShouldRun.load()) {
            // Do Stuff
            // Set threadXShouldRun to false when you're done
            // thread2ShouldRun.store(false);
        }
    }

public:
    worker() {}

    void start()
    {
        thread1ShouldRun.store(true);
        thread1 = std::thread(&worker::workerFunc1, this);
        thread2ShouldRun.store(true);
        thread2 = std::thread(&worker::workerFunc2, this);            
    }

    ~worker()
    {
        thread1ShouldRun.store(false);
        // Protection in case you create a worker that you delete and never call start()
        if (thread1.joinable())
            thread1.join();
        thread2ShouldRun.store(false);
        if (thread2.joinable())
            thread2.join();
    }
};

int main()
{
    worker *p_worker = new worker();
    p_worker->start();
    std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // 1 sec

    delete p_worker; // Threads will be joined here
}
类工作者
{
私人:
标准:螺纹1;
std::原子线程1应运行;
标准:螺纹2;
std::原子线程2应运行;
void workerFunc1(){
bool threadWorkIsDone=false;
while(thread1ShouldRun.load()){
//做事
//完成后,将threadXShouldRun设置为false
//thread1ShouldRun.store(false);
}
}
void workerFunc2(){
bool threadWorkIsDone=false;
while(thread2ShouldRun.load()){
//做事
//完成后,将threadXShouldRun设置为false
//thread2ShouldRun.store(false);
}
}
公众:
工作者(){}
void start()
{
thread1ShouldRun.store(true);
thread1=std::thread(&worker::workerFunc1,this);
thread2ShouldRun.store(true);
thread2=std::thread(&worker::workerFunc2,this);
}
~worker()
{
thread1ShouldRun.store(false);
//如果您创建了一个已删除但从未调用start()的工作进程,则提供保护
if(thread1.joinable())
thread1.join();
thread2ShouldRun.store(false);
if(thread2.joinable())
螺纹2.连接();
}
};
int main()
{
工人*p_工人=新工人();
p_worker->start();
std::this_thread::sleep_for(std::chrono::毫秒(1000));//1秒
delete p_worker;//线程将在此处联接
}

您不能加入已分离的thread@RichardCritten啊,对了-我会记住这一点来更新Q,谢谢:)一般来说,如果一个类“拥有”线程,你不会分离它们,以某种方式通知它们终止于析构函数并加入它们。“这是一种合理的方法吗?”为了什么?你的线程现在只是在睡觉,所以这很好;但是当你用它们做一些事情时,如果线程使用任何全局资源,那么它可能不好。如果你的线程在做一些CPU密集型的事情,那么它可能也不好,因为你想让它们停止而不是在某些服务器上工作50秒不能使用的东西。@MatteoItalia mm..很好的一点-我确信我需要分离它们以允许main继续。但我想我对不加入它们感到困惑,谢谢:)哦…该死!-所以如果std::terminate()调用,根据我的理解(承认不是太多!),则整个应用程序将终止…正如您所说,这不是好消息:(这是所有正确的信息,但可能应该为OP澄清一点;“如果它们仍然可连接”位表示“如果它们未分离并且仍在运行”。因此,这都意味着*如果您不加入非分离线程,您的程序将被终止“这里正确的操作过程是在
std::thread
被销毁之前进行连接。@MatteoItalia因此,如果线程在辅助析构函数中进行连接(就像我最初使用的那样,但没有分离),那么这种方法可能会起作用?-即std::terminate()不会被调用?是的。分离意味着启动独立的线程,可以自由运行(也可以通过其他方式加入)。如果你有线程的所有者,通常你希望在销毁线程时加入。我喜欢使用原子线程:)