concurrency_demo.cpp
C++_4th/Part_IV_Standard_Library/Chapter_34_Concurrency/concurrency_demo.cpp
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include <future>
#include <vector>
#include <queue>
#include <chrono>
#include <random>
#include <functional>
// Demonstrates C++ concurrency features
int main() {
std::cout << "C++ Concurrency Demonstration" << std::endl;
std::cout << "=============================" << std::endl;
// 1. Basic thread management
std::cout << "\n1. BASIC THREAD MANAGEMENT:" << std::endl;
auto worker_function = [](int id) {
std::cout << "Thread " << id << " started" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << "Thread " << id << " finished" << std::endl;
};
std::vector<std::thread> threads;
// Create multiple threads
for (int i = 0; i < 4; ++i) {
threads.emplace_back(worker_function, i);
}
// Wait for all threads to complete
for (auto& t : threads) {
t.join();
}
std::cout << "All threads completed" << std::endl;
// 2. Thread synchronization with mutex
std::cout << "\n2. THREAD SYNCHRONIZATION WITH MUTEX:" << std::endl;
std::mutex mtx;
int shared_counter = 0;
auto increment_function = [&mtx, &shared_counter](int id, int iterations) {
for (int i = 0; i < iterations; ++i) {
std::lock_guard<std::mutex> lock(mtx);
int old_value = shared_counter;
std::this_thread::sleep_for(std::chrono::microseconds(1));
shared_counter = old_value + 1;
}
};
std::vector<std::thread> sync_threads;
for (int i = 0; i < 4; ++i) {
sync_threads.emplace_back(increment_function, i, 1000);
}
for (auto& t : sync_threads) {
t.join();
}
std::cout << "Shared counter value: " << shared_counter << std::endl;
// 3. Atomic operations
std::cout << "\n3. ATOMIC OPERATIONS:" << std::endl;
std::atomic<int> atomic_counter(0);
auto atomic_increment = [&atomic_counter](int iterations) {
for (int i = 0; i < iterations; ++i) {
atomic_counter.fetch_add(1);
}
};
std::vector<std::thread> atomic_threads;
for (int i = 0; i < 4; ++i) {
atomic_threads.emplace_back(atomic_increment, 1000);
}
for (auto& t : atomic_threads) {
t.join();
}
std::cout << "Atomic counter value: " << atomic_counter.load() << std::endl;
// 4. Condition variables
std::cout << "\n4. CONDITION VARIABLES:" << std::endl;
std::mutex cv_mtx;
std::condition_variable cv;
bool ready = false;
std::queue<int> work_queue;
// Producer thread
auto producer = [&cv_mtx, &cv, &ready, &work_queue]() {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
{
std::lock_guard<std::mutex> lock(cv_mtx);
for (int i = 0; i < 5; ++i) {
work_queue.push(i);
}
ready = true;
}
cv.notify_one();
std::cout << "Producer finished" << std::endl;
};
// Consumer thread
auto consumer = [&cv_mtx, &cv, &ready, &work_queue]() {
std::unique_lock<std::mutex> lock(cv_mtx);
cv.wait(lock, [&ready] { return ready; });
std::cout << "Consumer processing: ";
while (!work_queue.empty()) {
std::cout << work_queue.front() << " ";
work_queue.pop();
}
std::cout << std::endl;
};
std::thread producer_thread(producer);
std::thread consumer_thread(consumer);
producer_thread.join();
consumer_thread.join();
// 5. Async programming with futures
std::cout << "\n5. ASYNC PROGRAMMING WITH FUTURES:" << std::endl;
auto compute_function = [](int n) -> int {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
return n * n;
};
// Launch async tasks
std::vector<std::future<int>> futures;
for (int i = 1; i <= 5; ++i) {
futures.push_back(std::async(std::launch::async, compute_function, i));
}
// Collect results
std::cout << "Async results: ";
for (auto& future : futures) {
std::cout << future.get() << " ";
}
std::cout << std::endl;
// 6. Promises and futures
std::cout << "\n6. PROMISES AND FUTURES:" << std::endl;
std::promise<int> promise;
std::future<int> future = promise.get_future();
auto promise_worker = [&promise]() {
std::this_thread::sleep_for(std::chrono::milliseconds(200));
promise.set_value(42);
};
std::thread promise_thread(promise_worker);
std::cout << "Waiting for promise result..." << std::endl;
int result = future.get();
std::cout << "Promise result: " << result << std::endl;
promise_thread.join();
// 7. Thread-safe container
std::cout << "\n7. THREAD-SAFE CONTAINER:" << std::endl;
class ThreadSafeQueue {
private:
std::queue<int> queue_;
mutable std::mutex mtx_;
std::condition_variable cv_;
public:
void push(int value) {
std::lock_guard<std::mutex> lock(mtx_);
queue_.push(value);
cv_.notify_one();
}
bool try_pop(int& value) {
std::lock_guard<std::mutex> lock(mtx_);
if (queue_.empty()) {
return false;
}
value = queue_.front();
queue_.pop();
return true;
}
void wait_and_pop(int& value) {
std::unique_lock<std::mutex> lock(mtx_);
cv_.wait(lock, [this] { return !queue_.empty(); });
value = queue_.front();
queue_.pop();
}
bool empty() const {
std::lock_guard<std::mutex> lock(mtx_);
return queue_.empty();
}
};
ThreadSafeQueue ts_queue;
// Producer
auto producer_ts = [&ts_queue]() {
for (int i = 0; i < 5; ++i) {
ts_queue.push(i);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
};
// Consumer
auto consumer_ts = [&ts_queue]() {
int value;
for (int i = 0; i < 5; ++i) {
ts_queue.wait_and_pop(value);
std::cout << "Consumed: " << value << std::endl;
}
};
std::thread producer_ts_thread(producer_ts);
std::thread consumer_ts_thread(consumer_ts);
producer_ts_thread.join();
consumer_ts_thread.join();
// 8. Thread pool simulation
std::cout << "\n8. THREAD POOL SIMULATION:" << std::endl;
class SimpleThreadPool {
private:
std::vector<std::thread> workers_;
std::queue<std::function<void()>> tasks_;
std::mutex queue_mutex_;
std::condition_variable condition_;
bool stop_;
public:
SimpleThreadPool(size_t num_threads) : stop_(false) {
for (size_t i = 0; i < num_threads; ++i) {
workers_.emplace_back([this] {
while (true) {
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(queue_mutex_);
condition_.wait(lock, [this] { return stop_ || !tasks_.empty(); });
if (stop_ && tasks_.empty()) {
return;
}
task = tasks_.front();
tasks_.pop();
}
task();
}
});
}
}
~SimpleThreadPool() {
{
std::unique_lock<std::mutex> lock(queue_mutex_);
stop_ = true;
}
condition_.notify_all();
for (std::thread& worker : workers_) {
worker.join();
}
}
template<typename F>
void enqueue(F&& f) {
{
std::unique_lock<std::mutex> lock(queue_mutex_);
tasks_.emplace(std::forward<F>(f));
}
condition_.notify_one();
}
};
SimpleThreadPool pool(4);
// Submit tasks to thread pool
for (int i = 0; i < 8; ++i) {
pool.enqueue([i]() {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << "Task " << i << " completed by thread "
<< std::this_thread::get_id() << std::endl;
});
}
std::this_thread::sleep_for(std::chrono::milliseconds(500));
// 9. Memory ordering with atomics
std::cout << "\n9. MEMORY ORDERING WITH ATOMICS:" << std::endl;
std::atomic<int> data(0);
std::atomic<bool> ready_flag(false);
auto writer = [&data, &ready_flag]() {
data.store(42, std::memory_order_relaxed);
ready_flag.store(true, std::memory_order_release);
};
auto reader = [&data, &ready_flag]() {
while (!ready_flag.load(std::memory_order_acquire)) {
std::this_thread::yield();
}
std::cout << "Data value: " << data.load(std::memory_order_relaxed) << std::endl;
};
std::thread writer_thread(writer);
std::thread reader_thread(reader);
writer_thread.join();
reader_thread.join();
// 10. Performance comparison
std::cout << "\n10. PERFORMANCE COMPARISON:" << std::endl;
const int num_iterations = 1000000;
// Sequential execution
auto start = std::chrono::high_resolution_clock::now();
int sequential_sum = 0;
for (int i = 0; i < num_iterations; ++i) {
sequential_sum += i;
}
auto end = std::chrono::high_resolution_clock::now();
auto sequential_time = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "Sequential execution time: " << sequential_time.count() << " ms" << std::endl;
std::cout << "Sequential sum: " << sequential_sum << std::endl;
// Parallel execution
start = std::chrono::high_resolution_clock::now();
std::atomic<int> parallel_sum(0);
const int num_threads = 4;
const int chunk_size = num_iterations / num_threads;
std::vector<std::thread> parallel_threads;
for (int t = 0; t < num_threads; ++t) {
int start_idx = t * chunk_size;
int end_idx = (t == num_threads - 1) ? num_iterations : (t + 1) * chunk_size;
parallel_threads.emplace_back([¶llel_sum, start_idx, end_idx]() {
int local_sum = 0;
for (int i = start_idx; i < end_idx; ++i) {
local_sum += i;
}
parallel_sum.fetch_add(local_sum);
});
}
for (auto& t : parallel_threads) {
t.join();
}
end = std::chrono::high_resolution_clock::now();
auto parallel_time = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "Parallel execution time: " << parallel_time.count() << " ms" << std::endl;
std::cout << "Parallel sum: " << parallel_sum.load() << std::endl;
std::cout << "\nConcurrency demonstration completed!" << std::endl;
return 0;
}
相关文章
vector_example.cpp
vector_example.cpp — cpp source code from the C++ 4th learning materials (C++_4th/Capstone_Project/examples/vector_example.cpp).
阅读文章 →algorithm.h
algorithm.h — c source code from the C++ 4th learning materials (C++_4th/Capstone_Project/include/mini_stl/algorithm.h).
阅读文章 →map.h
map.h — c source code from the C++ 4th learning materials (C++_4th/Capstone_Project/include/mini_stl/map.h).
阅读文章 →thread_pool.h
thread_pool.h — c source code from the C++ 4th learning materials (C++_4th/Capstone_Project/include/mini_stl/thread_pool.h).
阅读文章 →vector.h
vector.h — c source code from the C++ 4th learning materials (C++_4th/Capstone_Project/include/mini_stl/vector.h).
阅读文章 →template_metaprogramming.cpp
template_metaprogramming.cpp — cpp source code from the C++ 4th learning materials (C++_4th/Examples/Advanced_Features/template_metaprogramming.cpp).
阅读文章 →