Skip to content

Asynchrony

Build Status NuGet Version GitHub Tag Azure DevOps Tests

The asynchrony library provides a comprehensive set of modern C++23 header-only utilities for building asynchronous and multi-threaded applications. It leverages standard C++ library features like std::jthread, std::semaphore, std::deque, and C++ concepts to provide clean, efficient, and type-safe abstractions for common concurrency patterns.


Key Features & Components

Single-threaded Worker

Process items asynchronously in a dedicated worker thread with low overhead and full move semantics.

Read Guide →

Shared Thread Pool

Distribute work across a pool of threads consuming from a single shared queue with automatic load balancing.

Read Guide →

Round-Robin Pool

Minimize lock contention in high-throughput applications using per-thread queues and round-robin dispatch.

Read Guide →

Periodic Worker

Execute recurring background tasks or timers at regular intervals cleanly using RAII lifecycle management.

Read Guide →

Quick Start Examples

#include "siddiqsoft/simple_worker.hpp"
#include <iostream>
#include <chrono>

struct MyTask {
    std::string data;
    void operator()() { 
        std::println("Processing: {}", data);
    }
};

int main() {
    siddiqsoft::simple_worker<MyTask> worker{[](auto& task) {
        task();  // Execute the task
    }};

    // Queue work items
    for (int i = 0; i < 100; ++i) {
        worker.queue(MyTask{"data-" + std::to_string(i)});
    }

    std::this_thread::sleep_for(std::chrono::seconds(1));
    return 0;
}
#include "siddiqsoft/simple_pool.hpp"
#include <iostream>
#include <chrono>

struct MyTask {
    std::string data;
    void operator()() { 
        // The std::format() does not have serializer for get_id()..
        std::cout << "Thread " << std::this_thread::get_id()
                  << " processing " << data << std::endl;
    }
};

int main() {
    // Pool of worker threads sharing a single queue
    siddiqsoft::simple_pool<MyTask> pool{[](auto& task) {
        task();  // Execute task
    }};

    for (int i = 0; i < 1000; ++i) {
        pool.queue(MyTask{"item-" + std::to_string(i)});
    }

    std::this_thread::sleep_for(std::chrono::seconds(2));
    return 0;
}
#include "siddiqsoft/roundrobin_pool.hpp"
#include <iostream>
#include <chrono>

struct MyTask {
    std::string data;
    void operator()() { 
        std::println( "Round-robin item: {}" , data);
    }
};

int main() {
    // Multi-threaded pool with per-thread queues
    siddiqsoft::roundrobin_pool<MyTask> pool{[](auto& task) {
        task();
    }};

    for (int i = 0; i < 1000; ++i) {
        pool.queue(MyTask{"item-" + std::to_string(i)});
    }

    std::this_thread::sleep_for(std::chrono::seconds(2));
    return 0;
}
#include "siddiqsoft/periodic_worker.hpp"
#include <iostream>
#include <chrono>

int main() {
    // Execute callback every 500ms
    siddiqsoft::periodic_worker<> timer{
        []() {
            std::println("Tick!");
        },
        std::chrono::milliseconds(500)
    };

    std::this_thread::sleep_for(std::chrono::seconds(5));
    return 0;
}

Requirements & Compatibility

Requirement Details
Language Standard C++23 (requires std::jthread and std::stop_token)
GCC GCC 10+ (-std=c++23 -pthread)
MSVC MSVC 16.11+ / Visual Studio 2019+ (/std:c++23)
Clang Clang 10+ (-std=c++23 -fexperimental-library -pthread)
Platforms Windows, Linux, macOS
Dependencies Core library is header-only with zero required external dependencies. Optional: nlohmann/json for JSON serialization.

Design Goals

  • Zero External Core Dependencies: Built entirely on C++23 standard library primitives.
  • Move Semantics & Zero Copy: Full support for move-only types and perfect forwarding.
  • RAII Lifecycle: Thread lifetimes and resource cleanups are managed via deterministic destructors.
  • Exception Safety: Callbacks handle exceptions without aborting worker threads.
  • Type Safety: Concepts ensure compile-time verification of task types.