The last thing we need to decide is whether to join or detach it. We don’t really need to wait for it to finish, so we can simply detach. This approach is quite common and the reason is, there’s a good chance this will work fine. The problem is that the sendEmail function can’t be independent of everything, it’s still a part of the application. It must depend on some other object or resource, which have their own lifetimes. If we were to pass the topLevelResults by reference, the main thread might go out of this scope, destructing the topLevelResult , while the new thread is still using it (that’s when sending an email takes longer than the calculation). But even if it’s passed by value, all sorts of things might happen. The main thread (and the whole program) might finish early or sending the email might take longer.

Scenario 2

Imagine the same scenario, but this time instead of sending an email we have an extremely short operation (compared to calculation). As we’re really sure it’ll finish shortly, instead of thinking a correct place to join we simply detach it. The danger here theoretically is the same, but less probable in practice.

Scenario 3

If you google why or when should I detach a thread, you’ll probably find the term “background thread”. These kinds of threads are usually created at the beginning and keep working in the background the whole time. An example can be a logger. This scenario is the most common and with a little effort can be arranged safely, but, again, it’s not protected from the theoretical danger described above.

Solution