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

时间:2022-01-19 20:47:29

Sometime I have to use std::thread to 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
}

3 个解决方案

#1


88  

In the destructor of std::thread, std::terminate is called if:

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

  • the thread was not joined (with t.join())
  • 线程没有被连接(与t.join()))
  • and was not detached either (with t.detach())
  • 也没有被分离(与t.detach()))

Thus, you should always either join or detach a thread before the flows of execution reaches the destructor.

因此,您应该总是在执行流到达析构函数之前加入或分离一个线程。


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

当程序终止(即主返回)时,不等待在后台执行的其余分离线程;相反,它们的执行被挂起,它们的线程本地对象被销毁。

Crucially, this means that the stack of those threads is not unwound and 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 join or 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
  • 除非您需要有更大的灵活性,并且愿意提供一个同步机制来自己等待线程完成,在这种情况下,您可以使用detach

#2


17  

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

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

detach basically will release the resources needed to be able to implement join.

detach将释放实现join所需的资源。

#3


9  

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

当您分离线程时,这意味着您不必在退出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()在您有一个必须在后台完成的任务时是非常有用的,但是您并不关心它的执行。这通常是一些库的情况。他们可能会悄悄地创建一个后台工作线程,并将其分离,这样你甚至不会注意到它。

#1


88  

In the destructor of std::thread, std::terminate is called if:

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

  • the thread was not joined (with t.join())
  • 线程没有被连接(与t.join()))
  • and was not detached either (with t.detach())
  • 也没有被分离(与t.detach()))

Thus, you should always either join or detach a thread before the flows of execution reaches the destructor.

因此,您应该总是在执行流到达析构函数之前加入或分离一个线程。


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

当程序终止(即主返回)时,不等待在后台执行的其余分离线程;相反,它们的执行被挂起,它们的线程本地对象被销毁。

Crucially, this means that the stack of those threads is not unwound and 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 join or 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
  • 除非您需要有更大的灵活性,并且愿意提供一个同步机制来自己等待线程完成,在这种情况下,您可以使用detach

#2


17  

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

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

detach basically will release the resources needed to be able to implement join.

detach将释放实现join所需的资源。

#3


9  

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

当您分离线程时,这意味着您不必在退出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()在您有一个必须在后台完成的任务时是非常有用的,但是您并不关心它的执行。这通常是一些库的情况。他们可能会悄悄地创建一个后台工作线程,并将其分离,这样你甚至不会注意到它。