Hello Task

The minimal Capy program: a task that prints a message.

What You Will Learn

  • Creating a task<> coroutine

  • Using thread_pool as an execution context

  • Launching tasks with run_async

Prerequisites

  • C++20 compiler

  • Capy library installed

Source Code

#include <boost/capy.hpp>
#include <iostream>

using namespace boost::capy;

task<> say_hello()
{
    std::cout << "Hello from Capy!\n";
    co_return;
}

int main()
{
    thread_pool pool;
    run_async(pool.get_executor())(say_hello());
    return 0;
}

Build

add_executable(hello_task hello_task.cpp)
target_link_libraries(hello_task PRIVATE capy)

Walkthrough

The Task

task<> say_hello()
{
    std::cout << "Hello from Capy!\n";
    co_return;
}

task<> is equivalent to task<void>—a coroutine that completes without returning a value. The co_return keyword marks this as a coroutine.

Tasks are lazy: calling say_hello() creates a task object but does not execute the body. The "Hello" message is not printed until the task is launched.

The Thread Pool

thread_pool pool;

thread_pool provides an execution context with worker threads. By default, it creates one thread per CPU core.

The pool’s destructor waits for all work to complete before returning. This ensures the program doesn’t exit while tasks are running.

Launching

run_async(pool.get_executor())(say_hello());

run_async bridges non-coroutine code (like main) to coroutine code. The two-call syntax:

  1. run_async(pool.get_executor()) — Creates a launcher with the executor

  2. (say_hello()) — Accepts the task and starts execution

The task runs on one of the pool’s worker threads.

Output

Hello from Capy!

Exercises

  1. Modify say_hello to accept a std::string_view parameter and print it

  2. Create multiple tasks and launch them all

  3. Add a handler to run_async that prints when the task completes

Next Steps