c++多线程
在C++中,多线程编程是实现并发和并行处理的重要方式。C++11引入了标准的多线程支持,使得多线程编程更加简洁和安全。以下是一些关于C++多线程的关键内容和示例代码。
1. 线程的创建
C++11引入了std::thread类,用于创建和管理线程。
示例代码:
#include <iostream>
#include <thread>
void threadFunction(int num) {
std::cout << "Thread " << num << " is running." << std::endl;
}
int main() {
std::thread t1(threadFunction, 1); // 创建线程t1
std::thread t2(threadFunction, 2); // 创建线程t2
t1.join(); // 等待线程t1完成
t2.join(); // 等待线程t2完成
std::cout << "Main thread is done." << std::endl;
return 0;
}
2. 线程的同步
多线程编程中,线程同步是关键。C++提供了多种同步机制,如互斥锁(std::mutex)、条件变量(std::condition_variable)、锁(std::lock_guard和std::unique_lock)等。
示例代码:使用互斥锁
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx; // 互斥锁
void printBlock(int n, char c) {
std::lock_guard<std::mutex> lock(mtx); // 自动加锁和解锁
for (int i = 0; i < n; ++i) {
std::cout << c;
}
std::cout << '\n';
}
int main() {
std::thread t1(printBlock, 50, '*');
std::thread t2(printBlock, 50, '$');
t1.join();
t2.join();
return 0;
}
3. 线程池
线程池是一种常用的并发模式,用于管理线程的创建和销毁,避免频繁创建和销毁线程带来的开销。
示例代码:简单的线程池
#include <iostream>
#include <thread>
#include <vector>
#include <queue>
#include <functional>
#include <mutex>
#include <condition_variable>
class ThreadPool {
public:
ThreadPool(size_t numThreads) {
for (size_t i = 0; i < numThreads; ++i) {
workers.emplace_back(
[this] {
while (true) {
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(queueMutex);
condition.wait(lock, [this] { return stop || !tasks.empty(); });
if (stop && tasks.empty()) return;
task = std::move(tasks.front());
tasks.pop();
}
task();
}
}
);
}
}
~ThreadPool() {
{
std::unique_lock<std::mutex> lock(queueMutex);
stop = true;
}
condition.notify_all();
for (std::thread &worker : workers) {
worker.join();
}
}
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(queueMutex);
if (stop) throw std::runtime_error("enqueue on stopped ThreadPool");
tasks.emplace([task]() { (*task)(); });
}
condition.notify_one();
return res;
}
private:
std::vector<std::thread> workers;
std::queue<std::function<void()>> tasks;
std::mutex queueMutex;
std::condition_variable condition;
bool stop = false;
};
int main() {
ThreadPool pool(4);
auto result1 = pool.enqueue([](int answer) { return answer; }, 42);
auto result2 = pool.enqueue([](int answer) { return answer; }, 43);
std::cout << "Result 1: " << result1.get() << std::endl;
std::cout << "Result 2: " << result2.get() << std::endl;
return 0;
}
4. 线程安全的队列
线程安全的队列是多线程编程中常用的工具,用于在多个线程之间安全地传递数据。
示例代码:线程安全的队列
#include <iostream>
#include <queue>
#include <mutex>
#include <condition_variable>
template <typename T>
class ThreadSafeQueue {
private:
std::queue<T> queue;
std::mutex mtx;
std::condition_variable cv;
bool done = false;
public:
ThreadSafeQueue() = default;
ThreadSafeQueue(const ThreadSafeQueue&) = delete;
ThreadSafeQueue& operator=(const ThreadSafeQueue&) = delete;
void push(T value) {
std::lock_guard<std::mutex> lock(mtx);
queue.push(std::move(value));
cv.notify_one();
}
T pop() {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [this] { return !queue.empty() || done; });
if (queue.empty()) throw std::runtime_error("No more elements");
T tmp = std::move(queue.front());
queue.pop();
return tmp;
}
void stop() {
std::unique_lock<std::mutex> lock(mtx);
done = true;
cv.notify_all();
}
bool empty() const {
std::lock_guard<std::mutex> lock(mtx);
return queue.empty();
}
};
int main() {
ThreadSafeQueue<int> queue;
std::thread producer([&queue] {
for (int i = 0; i < 10; ++i) {
queue.push(i);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
queue.stop();
});
std::thread consumer([&queue] {
while (true) {
try {
int value = queue.pop();
std::cout << "Consumed: " << value << std::endl;
} catch (const std::runtime_error& e) {
std::cout << e.what() << std::endl;
break;
}
}
});
producer.join();
consumer.join();
return 0;
}
5. 线程的性能优化
在多线程编程中,性能优化是一个重要的方面。以下是一些常见的优化技巧:
- 减少锁的使用:尽量减少锁的使用范围,避免锁的过度竞争。
- 使用无锁编程:在某些情况下,可以使用无锁数据结构来提高性能。
- 合理分配线程:根据系统的CPU核心数合理分配线程数量,避免过多线程导致的上下文切换开销。
6. 线程的异常处理
在多线程编程中,异常处理是一个重要的问题。C++11提供了std::future和std::promise来支持线程间的异常传递。
示例代码:线程异常处理
#include <iostream>
#include <thread>
#include <future>
#include <exception>
int main() {
std::promise<int> result;
std::future<int> future = result.get_future();
std::thread worker([&result] {
try {
throw std::runtime_error("Something went wrong");
} catch (...) {
result.set_exception(std::current_exception());
}
});
try {
std::cout << "The answer is (should be exception): " << future.get() << std::endl;
} catch (std::exception& e) {
std::cout << "Caught exception: " << e.what() << std::endl;
}
worker.join();
return 0;
}
7. 线程的资源管理
在多线程编程中,资源管理是一个重要的问题。C++11提供了std::shared_ptr和std::unique_ptr来支持线程间的资源管理。
示例代码:线程资源管理
#include <iostream>
#include <thread>
#include <memory>
void worker(std::shared_ptr<int> ptr) {
std::cout << "Worker thread: " << *ptr << std::endl;
}
int main() {
std::shared_ptr<int> ptr = std::make_shared<int>(42);
std::thread t(worker, ptr);
std::cout << "Main thread: " << *ptr << std::endl;
t.join();
return 0;
}