std::packag..._thread_exit(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’… NAME πŸ’…

okay bestie, you're on the std::packag..._thread_exit(3) page from the C++ Standard Libary manual β€” yes, that's the manual name, and we're keeping it cute. The actual star of the show is:

  • std::packaged_task::make_ready_at_thread_exit β€” std::packaged_task::make_ready_at_thread_exit

🌸 Synopsis 🌸

void make_ready_at_thread_exit( ArgTypes... args );  (since C++11)

So what's the tea? It calls the stored task as if by INVOKE<R>(f, args...), where f is the stored task. The return value of the task β€” or any exception it throws β€” gets stored in the shared state of *this. πŸ’–

But here's the dramatic part: the shared state is only made ready after the current thread exits and all objects of thread-local storage duration are destroyed. It's giving "wait for the glow-up to finish" energy, no cap. ✨


πŸŽ€ Parameters πŸŽ€

  • args β€” the parameters to pass on invocation of the stored task.

πŸ¦‹ Return value πŸ¦‹

(none) β€” literally nothing, bestie.


😭 Exceptions 😭

std::future_error is the vibe on the following error conditions:

  • The stored task has already been invoked. The error category is set to promise_already_satisfied.
  • *this has no shared state. The error category is set to no_state.

✨ Example ✨

// Run this code
#include <chrono>
#include <functional>
#include <future>
#include <iostream>
#include <thread>
#include <utility>

void worker(std::future<void>& output)
{
    std::packaged_task<void(bool&)> my_task{[](bool& done) { done =
    true; }};
    auto result = my_task.get_future();

    bool done = false;
    my_task.make_ready_at_thread_exit(done); // execute task right away

    std::cout << "worker: done = " << std::boolalpha << done <<
    std::endl;

    auto status = result.wait_for(std::chrono::seconds(0));
    if (status == std::future_status::timeout)
        std::cout << "worker: result is not ready yet" << std::endl;

    output = std::move(result);
}

int main()
{
    std::future<void> result;

    std::thread{worker, std::ref(result)}.join();

    auto status = result.wait_for(std::chrono::seconds(0));
    if (status == std::future_status::ready)
        std::cout << "main: result is ready" << std::endl;
}

Output:

worker: done = true
worker: result is not ready yet
main: result is ready

πŸ‘€ See also πŸ‘€

  • operator() β€” executes the function (public member function).

source: http://cppreference.com Β· version/date: 2024.06.10 Β· page: std::packag..._thread_exit(3) β€” mwah πŸ’‹

πŸ“¦ where this page comes from