解锁C++多线程编程:实战示例,轻松掌握并发编程核心技巧
引言
C++作为一种强大的编程语言,支持多线程编程,使得开发者能够利用多核处理器的能力,提高程序的执行效率。然而,多线程编程也带来了复杂性,需要开发者掌握核心技巧以避免常见错误。本文将通过实战示例,帮助读者轻松掌握C++多线程编程的核心技巧。
一、C++多线程编程基础
1.1 线程创建
在C++中,可以使用std::thread类创建线程。以下是一个简单的示例:
#include <iostream> #include <thread> void threadFunction() { std::cout << "Thread is running..." << std::endl; } int main() { std::thread t(threadFunction); t.join(); // 等待线程结束 return 0; } 1.2 线程同步
线程同步是避免竞态条件的关键。C++提供了多种同步机制,如互斥锁(std::mutex)、条件变量(std::condition_variable)和原子操作(std::atomic)。
1.2.1 互斥锁
以下是一个使用互斥锁保护共享资源的示例:
#include <iostream> #include <mutex> std::mutex mtx; void printBlock(int n, char c) { mtx.lock(); std::cout << n << ": " << c << std::endl; mtx.unlock(); } int main() { std::thread t1(printBlock, 1, 'A'); std::thread t2(printBlock, 2, 'B'); t1.join(); t2.join(); return 0; } 1.2.2 条件变量
条件变量用于线程间的通信。以下是一个使用条件变量的示例:
#include <iostream> #include <thread> #include <mutex> #include <condition_variable> std::mutex mtx; std::condition_variable cv; bool ready = false; void waitThread() { std::unique_lock<std::mutex> lck(mtx); cv.wait(lck, []{return ready;}); std::cout << "Thread is running..." << std::endl; } void signalThread() { std::unique_lock<std::mutex> lck(mtx); ready = true; cv.notify_one(); } int main() { std::thread t1(waitThread); std::thread t2(signalThread); t1.join(); t2.join(); return 0; } 1.2.3 原子操作
原子操作用于保证操作的原子性。以下是一个使用原子操作的示例:
#include <iostream> #include <thread> #include <atomic> std::atomic<int> counter(0); void increment() { for (int i = 0; i < 1000; ++i) { ++counter; } } int main() { std::thread t1(increment); std::thread t2(increment); t1.join(); t2.join(); std::cout << "Counter: " << counter << std::endl; return 0; } 二、线程池
线程池可以有效地管理线程资源,提高程序的并发性能。以下是一个简单的线程池实现:
#include <iostream> #include <vector> #include <thread> #include <functional> #include <queue> #include <mutex> #include <condition_variable> class ThreadPool { public: ThreadPool(size_t threads) : stop(false) { for (size_t i = 0; i < threads; ++i) { workers.emplace_back([this] { for (;;) { std::function<void()> task; { std::unique_lock<std::mutex> lock(this->queue_mutex); this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); }); if (this->stop && this->tasks.empty()) return; task = std::move(this->tasks.front()); this->tasks.pop(); } task(); } }); } } template<class F, class... Args> auto enqueue(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type> { using return_type = typename std::result_of<F(Args...)>::type; auto task = std::make_shared< std::packaged_task<return_type()> >( std::bind(std::forward<F>(f), std::forward<Args>(args)...) ); std::future<return_type> res = task->get_future(); { std::unique_lock<std::mutex> lock(queue_mutex); if (stop) throw std::runtime_error("enqueue on stopped ThreadPool"); tasks.emplace([task](){ (*task)(); }); } condition.notify_one(); return res; } ~ThreadPool() { { std::unique_lock<std::mutex> lock(queue_mutex); stop = true; } condition.notify_all(); for (std::thread &worker: workers) worker.join(); } private: std::vector<std::thread> workers; std::queue< std::function<void()> > tasks; std::mutex queue_mutex; std::condition_variable condition; bool stop; }; 三、总结
本文通过实战示例,介绍了C++多线程编程的基础知识和核心技巧。掌握这些技巧,可以帮助开发者编写高效、可靠的并发程序。在实际开发中,还需不断学习和实践,以应对各种复杂场景。
支付宝扫一扫
微信扫一扫