Use this file to discover all available pages before exploring further.
The Concurrency Runtime (ConcRT) is a cooperative concurrency framework built into the MSVC toolchain that provides high-level abstractions for parallel and asynchronous programming. It consists of three layers: the Parallel Patterns Library (PPL) for parallel algorithms and task parallelism, the Asynchronous Agents Library for dataflow and message-passing concurrency, and the Task Scheduler for fine-grained scheduling control. Unlike raw thread-based programming, ConcRT’s cooperative scheduler avoids oversubscription by adapting thread usage to available hardware cores and work volume.
The Concurrency Runtime relies on C++11 features including lambdas, auto, range-based for, and move semantics. Ensure your project targets C++11 or later (Project Properties → C/C++ → Language → C++ Language Standard → ISO C++14 or higher).
task_group allows dynamic task creation where the number of tasks is not known at compile time. It provides explicit wait() and cancel() support.
#include <ppl.h>#include <vector>#include <iostream>using namespace concurrency;int main() { task_group tg; std::vector<int> inputs = {1, 2, 3, 4, 5, 6, 7, 8}; // Submit tasks dynamically for (int x : inputs) { tg.run([x]() { // Each task processes one input printf("Processing %d → %d\n", x, x * x); }); } // Wait for all submitted tasks to finish tg.wait(); std::cout << "All tasks done.\n"; return 0;}
Prefer task_group over task when you need explicit cancellation via structured_task_group::cancel(). Use task (from <ppltasks.h>) when you need continuations (.then()) and composability.
The PPL provides thread-safe containers that allow concurrent reads and writes without external locking:
concurrent_vector
concurrent_vector<T> allows concurrent push_back and element access. Elements are never moved once inserted, so existing iterators/pointers remain valid.
The Asynchronous Agents Library enables dataflow programming using message-passing between agents. Agents communicate through message blocks (unbounded_buffer, call, transformer) without sharing state.
#include <agents.h>#include <iostream>#include <string>using namespace concurrency;// A simple pipeline: producer → transformer → consumerint main() { // Result buffer receives output from the transformer unbounded_buffer<std::string> result_buffer; // Transformer: converts int → string representation. // The optional second constructor arg is the downstream target. transformer<int, std::string> convert_agent( [](int n) -> std::string { return "Item: " + std::to_string(n * n); }, &result_buffer // forward transformed output here ); // Producer: send 5 items directly into the transformer for (int i = 1; i <= 5; i++) { send(convert_agent, i); } // Consumer: receive and display results for (int i = 0; i < 5; i++) { std::string result = receive(result_buffer); std::cout << result << "\n"; } return 0;}