Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can std::thread/jthread exit without executing passed function?

Is it possible that joining std::thread or std::jthread too quickly (before the thread can actually be started in OS) cause the thread to not execute at all? Or is it guaranteed that it will simply block the parent thread until the child thread starts, executes and finishes?

I thought it's quite obvious that it should execute, but my colleague said it doesn't have to happen if std::stop_source is already triggered on jthread before the callback is called, hence my confusion.

Example:

#include <thread>
#include <iostream>

void foo()
{
    std::cout << "foo()" << std::endl;
}

int main()
{
    std::jthread{foo};
    std::thread{foo}.join();
}

This outputs:

foo()
foo()

ThreadSanitizer doesn't report issues either, but I'd like to have some confirmation from standard.

like image 771
Yksisarvinen Avatar asked Feb 06 '26 00:02

Yksisarvinen


1 Answers

The constructor ensures and synchronises with the invocation of the passed function

Effects: The new thread of execution executes invoke(auto(std::forward<F>(f)), auto(std::forward<Args>(args))...) with the values produced by auto being materialized ([conv.rval]) in the constructing thread. Any return value from this invocation is ignored.

Synchronization: The completion of the invocation of the constructor synchronizes with the beginning of the invocation of the copy of f.

[thread.thread.constr]

The join synchronises with the end of the thread

Synchronization: The completion of the thread represented by *this synchronizes with ([intro.multithread]) the corresponding successful join() return.

[thread.thread.member]

Similar wording is present for jthread, except that it might pass it's stop_token to f

Signalling a stop_source doesn't stop a jthread, it is up to the invoked code to inspect the stop_token and finish.

like image 120
Caleth Avatar answered Feb 07 '26 14:02

Caleth