Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::terminate is called due to uncaught exception inside of joined thread

I am wondering why exceptions inside joined thread invoke std::terminate and detached threads do not invoke std::terminate.

Consider following snippet that triggers std::terminate. If we replace t2.join() with t2.detach() the program will exit with 0.

#include <thread>
#include <print>

void foo(bool throws) {
    if (throws) {
        throw std::runtime_error("Asked to throw");
    }
}

int main() {
    try {
        std::thread t1(foo, false);
        std::thread t2(foo, true);
        t1.join();
        t2.join();
    }
    catch (std::exception const &e) {
        std::println("Failed with exception: {}", e.what());
    }
}
like image 974
vocasle Avatar asked Oct 14 '25 03:10

vocasle


1 Answers

You have a race condition. If you want to transport exception from another thread to the main thread you can use std::future + std::async. Side note, when starting threads/async calls use lambda expressions like this example does.

#include <thread>
#include <print>
#include <future>

void foo(bool throws) 
{
    if (throws) 
    {
        throw std::runtime_error("Asked to throw");
    }
}

int main() 
{
    try 
    {
        std::future<void> async_no_throw = std::async(std::launch::async, [] { foo(false); });
        std::future<void> async_throw = std::async(std::launch::async, [] { foo(true); });

        async_no_throw.get();
        async_throw.get(); // this will synchronize and rethrow
    }
    catch (std::exception const& e) 
    {
        std::println("Failed with exception: {}", e.what());
    }
}
like image 139
Pepijn Kramer Avatar answered Oct 20 '25 08:10

Pepijn Kramer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!