C++ 我什么时候应该使用 std::thread::detach?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22803600/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:13:46  来源:igfitidea点击:

When should I use std::thread::detach?

c++c++11stdthread

提问by Jinbom Heo

Sometime I have to use std::threadto speed up my application. I also know join()waits until a thread completes. This is easy to understand, but what's the difference between calling detach()and not calling it?

有时我必须用来std::thread加速我的应用程序。我也知道join()等待线程完成。这很容易理解,但是调用detach()和不调用有什么区别呢?

I thought that without detach(), the thread's method will work using a thread independently.

我认为没有detach(),线程的方法将独立使用线程工作。

Not detaching:

不分离:

void Someclass::Somefunction() {
    //...

    std::thread t([ ] {
        printf("thread called without detach");
    });

    //some code here
}

Calling with detaching:

调用分离:

void Someclass::Somefunction() {
    //...

    std::thread t([ ] {
        printf("thread called with detach");
    });

    t.detach();

    //some code here
}

回答by Matthieu M.

In the destructor of std::thread, std::terminateis called if:

在 , 的析构函数中std::threadstd::terminate如果:

  • the thread was not joined (with t.join())
  • and was not detached either (with t.detach())
  • 该线程未加入(与t.join()
  • 并且也没有分离(与t.detach()

Thus, you should always either joinor detacha thread before the flows of execution reaches the destructor.

因此,在执行流程到达析构函数之前,您应该始终选择一个线程joindetach一个线程。



When a program terminates (ie, mainreturns) the remaining detached threads executing in the background are not waited upon; instead their execution is suspended and their thread-local objects destructed.

当程序终止(即main返回)时,不等待在后台执行的剩余分离线程;相反,它们的执行被暂停并且它们的线程本地对象被破坏。

Crucially, this means that the stack of those threads is not unwoundand thus some destructors are not executed. Depending on the actions those destructors were supposed to undertake, this might be as bad a situation as if the program had crashed or had been killed. Hopefully the OS will release the locks on files, etc... but you could have corrupted shared memory, half-written files, and the like.

至关重要的是,这意味着这些线程的堆栈不会展开,因此不会执行某些析构函数。根据这些析构函数应该采取的行动,这可能是一个糟糕的情况,就像程序崩溃或被杀死一样。希望操作系统会释放对文件等的锁定……但您可能已经损坏了共享内存、写了一半的文件等。



So, should you use joinor detach?

那么,你应该使用join还是detach

  • Use join
  • Unless you need to have more flexibility AND are willing to provide a synchronization mechanism to wait for the thread completion on your own, in which case you may use detach
  • join
  • 除非您需要更大的灵活性并且愿意提供一个同步机制来等待您自己的线程完成,在这种情况下您可以使用detach

回答by 6502

You should call detachif you're not going to wait for the thread to complete with joinbut the thread instead will just keep running until it's done and then terminate without having the main thread waiting for it specifically.

detach如果您不打算等待线程完成,则应该调用,join但线程将继续运行直到完成,然后终止而无需主线程专门等待它。

detachbasically will release the resources needed to be able to implement join.

detach基本上会释放出能够执行所需的资源join

It is a fatal error if a thread object ends its life and neither joinnor detachhas been called; in this case terminateis invoked.

如果一个线程对象结束它的生命并且既join没有detach被调用也没有被调用,这是一个致命错误;在这种情况下terminate被调用。

回答by GreenScape

When you detach thread it means that you don't have to join()it before exiting main().

当您分离线程时,这意味着您join()在退出之前不必使用它main()

Thread library will actually wait for each such thread below-main, but you should not care about it.

线程库实际上会在 main 下等待每个这样的线程,但你不应该关心它。

detach()is mainly useful when you have a task that has to be done in background, but you don't care about its execution. This is usually a case for some libraries. They may silently create a background worker thread and detach it so you won't even notice it.

detach()当您有一个必须在后台完成的任务,但您不关心它的执行时,这主要是有用的。这通常是某些图书馆的情况。他们可能会默默地创建一个后台工作线程并将其分离,因此您甚至不会注意到它。

回答by user7860670

This answer is aimed at answering question in the title, rather than explaining the difference between joinand detach. So when should std::thread::detachshould be used?

这个答案的目的是在标题答题,而不是解释之间的差异joindetach。那么应该std::thread::detach什么时候使用呢?

In properly maintained C++ code std::thread::detachshould not be used at all. Programmer must ensure that all the created threads gracefully exit releasing all the acquired resources and performing other necessary cleanup actions. This implies that giving up ownership of threads by invoking detachis not an option and therefore joinshould be used in all scenarios.

在正确维护的 C++ 代码中std::thread::detach根本不应该使用。程序员必须确保所有创建的线程优雅地退出,释放所有获取的资源并执行其他必要的清理操作。这意味着通过调用放弃线程的所有权detach不是一种选择,因此join应该在所有场景中使用。

However some applications rely on old and often not well designed and supported APIs that may contain indefinitely blocking functions. Moving invocations of these functions into a dedicated thread to avoid blocking other stuff is a common practice. There is no way to make such a thread to exit gracefully so use of joinwill just lead to primary thread blocking. That's a situation when using detachwould be a less evil alternative to, say, allocating threadobject with dynamic storage duration and then purposely leaking it.

然而,一些应用程序依赖于可能包含无限期阻塞功能的旧的且通常设计和支持不佳的 API。将这些函数的调用移动到专用线程中以避免阻塞其他东西是一种常见的做法。没有办法让这样的线程优雅地退出,所以使用join只会导致主线程阻塞。在这种情况下, usingdetach将是一种不那么邪恶的替代方案,例如,分配thread具有动态存储持续时间的对象然后故意泄漏它。

#include <LegacyApi.hpp>
#include <thread>

auto LegacyApiThreadEntry(void)
{
    auto result{NastyBlockingFunction()};
    // do something...
}

int main()
{
    ::std::thread legacy_api_thread{&LegacyApiThreadEntry};
    // do something...
    legacy_api_thread.detach();
    return 0;
}

回答by DinoStray

According to cppreference.com:

根据cppreference.com

Separates the thread of execution from the thread object, allowing execution to continue independently. Any allocated resources will be freed once the thread exits.

After calling detach *thisno longer owns any thread.

将执行线程与线程对象分开,允许独立继续执行。一旦线程退出,任何分配的资源都将被释放。

调用 detach 后*this不再拥有任何线程。

For example:

例如:

  std::thread my_thread([&](){XXXX});
  my_thread.detach();

Notice the local variable: my_thread, while the lifetime of my_threadis over, the destructor of std::threadwill be called, and std::terminate()will be called within the destructor.

注意局部变量: my_thread,当 of 的生命周期my_thread结束时,std::thread将调用of 的析构函数,并将在析构函数中调用std::terminate()

But if you use detach(), you should not use my_threadanymore, even if the lifetime of my_threadis over, nothing will happen to the new thread.

但是如果detach()使用my_thread了,就不应该再使用了,即使 的生命周期my_thread结束,新线程也不会发生任何事情。