0

I am writing the following c++ code to create a detach thread :

void threadF() {
    ofstream        f("data") ;
    for(int i=1; i<=5; i++) {
            f<<"t1:::"<<i<<"\n" ;
            f.flush() ;
            sleep(1) ;
    }
    f.close() ;
}

int main() {

    thread t1(threadF) ;

    cout<<"main #1\n" ;
    sleep(2) ;
    t1.detach() ;
    cout<<"main #2\n" ;
}

When I run this code, I have the following observations :

  1. main exits after 2 secs (as expected)
  2. the detach child thread also seems to be running only for 2secs because the output data file contains only 2 lines.

I expected that the thread should have executed completely and that the output data file should have contained 5 lines. This is not happening

I need an explanation for this behavior.

AS per the ink What happens to a detached thread when main() exits?, does it mean that the detached thread would automatically terminate when the main exits ?

user3282758
  • 1,379
  • 11
  • 29
  • If you want to wait for a thread completion, `join()` it. – Evg Aug 07 '21 at 10:11
  • 5
    Returning from `main` ends the process, it kills all running threads. Using `detatch` is usually an error. You have no idea at what point the thread will die. It might die while writing to the file and (depending on the OS and file system) it could leave it in a corrupted state. – François Andrieux Aug 07 '21 at 10:16
  • This doesn't address the question, but you don't need to call `f.close() ;`. The destructor will do that. – Pete Becker Aug 07 '21 at 12:07
  • 'Using detatch is usually an error' nope. – Martin James Aug 08 '21 at 09:34

1 Answers1

1

I need an explanation for this behavior.

When main returns, the process is terminated. If there was a thread running, there are no guarantees that it will have a chance to finish.

Furthermore, technically touching any global state after main has returned results in undefined behaviour because all static storage objects will be destroyed by the main thread.

Basically, std::thread::detach is rarely useful because you simply have to use some other way to join the thread instead. There's no standard way to "wait for all detached threads and then stop". There are platform specific ways though (pthread_exit).

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • `thread::detach` is useful in the _limited_ case where you want what a certain other programming language calls a "daemon thread." That is, a long-running thread, that performs some service within the running program, but which does _not_ modify any persistent state, and which therefore can not cause any permanent harm when it is abruptly terminated. An example might be a thread that manages some kind of an in-memory data cache. François Andrieux said that `detach` is usually an error. I would call it a "code smell"--a reason extra scrutiny in a code review. – Solomon Slow Aug 07 '21 at 13:03
  • Every thread I have used in the last 30 years runs detached and is not joined. It is continual create/terminate/join that is the anti-pattern. App-lifetime and pooled threads are fine. Create/join should be a last resort. – Martin James Aug 08 '21 at 09:39
  • 1
    @MartinJames, "create/join" does not have to be continual. There are use-cases for having the main thread `join` a long-running, "background" thread before the process termiantes. (E.g., if the background thread updates some persistent resource.) OTOH, Anybody who wants to design a new program that behaves in that way may want to do some reading on the subject of [_crash-only software_](https://en.wikipedia.org/wiki/Crash-only_software) before they begin. – Solomon Slow Aug 12 '21 at 15:34