asynchrony 0.0.0
Add asynchrony to your C++ applications using standard C++20
Loading...
Searching...
No Matches
Quick Reference

Components at a Glance

Component Use Case Threads Queue Type
simple_worker Single async task 1 Shared
simple_pool Parallel processing N Shared
roundrobin_pool Load balancing N Per-thread
periodic_worker Scheduled tasks 1 N/A
resource_pool Resource management N/A N/A

Include Files

#include "siddiqsoft/simple_worker.hpp" // Single-threaded worker
#include "siddiqsoft/simple_pool.hpp" // Multi-threaded pool
#include "siddiqsoft/roundrobin_pool.hpp" // Round-robin pool
#include "siddiqsoft/periodic_worker.hpp" // Periodic executor
#include "siddiqsoft/resource_pool.hpp" // Resource pool

Basic Patterns

Single Worker

[](auto&& task) { task.execute(); }
};
worker.queue(std::move(task));
Implements a simple queue + semaphore driven asynchronous processor.
void queue(T &&item)
Queue item into this worker thread's deque.

Thread Pool

[](auto&& task) { task.execute(); }
};
for (auto& t : tasks) pool.queue(std::move(t));
Implements a single deque based vector of jthreads. All threads wait on the next available item via s...
void queue(T &&item)
Queue item into the deque (takes "ownership" of the item).

Round-Robin Pool

[](auto&& task) { task.execute(); }
};
for (auto& t : tasks) pool.queue(std::move(t));
Implements a lock-free round robin work allocation into vector of simple_worker<T>.
void queue(T &&item)
Queue item into one of the thread's queue.

Periodic Task

[]() { /* do something */ },
std::chrono::milliseconds(1000)
};
Implements a simple queue + semaphore driven asynchronous processor.

Resource Pool

auto res = pool.checkout();
// use resource
pool.checkin(std::move(res));
Implements a resource pool that stores objects of type T. Said objects can be shared_ptr or unique_pt...
void checkin(T &&rsrc)
Insert a new element or return a borrowed element.

Template Parameters

simple_worker<T, Pri>

  • T: Data type (must be move-constructible)
  • Pri: Thread priority (-10 to +10, default 0)

simple_pool<T, N>

  • T: Data type (must be move-constructible)
  • N: Number of threads (0 = hardware_concurrency)

roundrobin_pool<T, N>

  • T: Data type (must be move-constructible)
  • N: Number of threads (0 = hardware_concurrency)

periodic_worker<Pri>

  • Pri: Thread priority (-10 to +10, default 0)

resource_pool<T>

  • T: Resource type (must be move-constructible)

Common Methods

queue(T&& item)

Queue an item for processing

worker.queue(std::move(item));

toJson()

Get JSON representation (requires nlohmann/json)

auto json = worker.toJson();
std::cout << json.dump(2) << std::endl;

checkout() / checkin()

Resource pool operations

auto resource = pool.checkout(); // throws if empty
// use resource
pool.checkin(std::move(resource));

size()

Get current pool size

auto sz = pool.size();
auto size()
Get the current size of the pool FIX: Removed unnecessary empty check - return size unconditionally T...

clear()

Clear all resources from pool

pool.clear();
void clear()
Clear all items from the pool FIX: Removed unnecessary empty check - clear() is safe on empty deque.

Requirements

  • C++20 or later
  • Compiler: GCC 10+, MSVC 16.11+, Clang 10+
  • Platform: Windows, Linux, macOS
  • Dependencies: None (header-only for core functionality)
  • Optional: nlohmann/json for JSON serialization

Compilation

GCC/Clang:

g++ -std=c++20 -pthread your_file.cpp
clang++ -std=c++20 -fexperimental-library -pthread your_file.cpp

MSVC:

cl /std:c++20 your_file.cpp

CMake:

target_link_libraries(your_target PRIVATE asynchrony::asynchrony)

Tips & Tricks

  1. Keep callbacks lightweight - Avoid blocking operations
  2. Use move semantics - Always move items into the queue
  3. Handle exceptions - Catch exceptions in callbacks
  4. Monitor queue depth - Check for bottlenecks using toJson()
  5. Choose right pool type - Use roundrobin for variable-duration tasks
  6. Lifetime management - Keep worker/pool alive while queuing
  7. Thread priority - Use carefully, may affect system performance
  8. Resource pool capacity - Set to match thread pool size for optimal performance

Common Issues

Issue Solution
Compilation error: jthread not found Use C++20 or later
Tasks not executing Ensure worker/pool is not destroyed
High CPU usage Increase wait timeout or reduce threads
Deadlock Avoid circular dependencies in callbacks
Memory leak Ensure proper RAII cleanup
checkout() throws Pool is empty, add resources first
Clang compilation fails Add -fexperimental-library flag

Performance Tips

  • CPU-bound tasks: Use threads = hardware_concurrency()
  • I/O-bound tasks: Use threads > hardware_concurrency()
  • Batch small tasks: Reduce overhead
  • Use roundrobin: For variable-duration tasks
  • Monitor metrics: Use toJson() to track queue depth
  • Avoid blocking: Keep callbacks fast and non-blocking

Quick Examples

Example 1: Simple Async Task

[](auto&& msg) { std::cout << msg << std::endl; }
};
worker.queue("Hello, World!");
std::this_thread::sleep_for(std::chrono::milliseconds(100));

Example 2: Parallel Processing

[](auto&& num) { std::cout << num * 2 << std::endl; }
};
for (int i = 0; i < 100; ++i) pool.queue(i);
std::this_thread::sleep_for(std::chrono::seconds(1));

Example 3: Periodic Monitoring

[]() { std::cout << "Tick!" << std::endl; },
std::chrono::seconds(1)
};
std::this_thread::sleep_for(std::chrono::seconds(10));

Example 4: Resource Management

auto conn = pool.checkout();
conn.query("SELECT * FROM users");
pool.checkin(std::move(conn));

JSON Output Format

When calling toJson() on workers, the output includes:

{
"_typver": "siddiqsoft.asynchrony-lib.simple_worker/0.10",
"itemsSize": 5,
"queueCounter": 100,
"itemsQueued": 100,
"itemsPopped": 95,
"itemsOutstanding": 5,
"threadPriority": 0,
"outstandingCallback": 1,
"waitInterval": 1500
}