在现代计算机系统中,多线程编程是一种常见的并发编程方式,它可以充分利用多核CPU的性能,提高程序的执行效率。C++从C++11开始,就在标准库中提供了对多线程编程的支持。本文将介绍C++多线程编程的基础知识和一些常见的使用技巧。
一、C++线程创建与管理
在C++中,我们可以通过`std::thread`类创建一个新的线程。`std::thread`的构造函数接受一个函数或者可调用对象,以及该函数或者对象的参数。例如:
```cpp
#include <iostream>
#include <thread>
void hello() {
std::cout << "Hello, World!" << std::endl;
}
int main() {
std::thread t(hello);
t.join();
return 0;
}
```
在这个例子中,我们创建了一个新的线程`t`,这个线程执行函数`hello`。`t.join()`会阻塞当前线程,直到`t`线程执行完毕。
二、线程同步
当多个线程共享数据时,我们需要使用同步机制来确保数据的一致性。C++提供了多种同步机制,如互斥量(`std::mutex`)、条件变量(`std::condition_variable`)等。
以下是一个使用`std::mutex`的例子:
```cpp
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
void print_block(int n, char c) {
mtx.lock();
for (int i = 0; i < n; ++i) { std::cout << c; }
std::cout << '\n';
mtx.unlock();
}
int main() {
std::thread th1(print_block, 50, '*');
std::thread th2(print_block, 50, '$');
th1.join();
th2.join();
return 0;
}
```
在这个例子中,我们使用一个互斥量`mtx`来保证`print_block`函数的原子性,防止两个线程同时输出到控制台。
## 三、线程间通信
线程间通信通常通过共享数据或者条件变量来实现。以下是一个使用`std::condition_variable`的例子:
``cpp
#include <iostream>
#include <thread>
#include <condition_variable>
#include <queue>
std::queue<int> produced_nums;
std::mutex mtx;
std::condition_variable cv;
void producer() {
for (int i = 0; ; i++) {
std::this_thread::sleep_for(std::chrono::milliseconds(900));
std::unique_lock<std::mutex> lock(mtx);
std::cout << "producing " << i << std::endl;
produced_nums.push(i);
cv.notify_all();
}
}
void consumer() {
while (true) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, []{return !produced_nums.empty();});
std::cout << "consuming " << produced_nums.front() << std::endl;
produced_nums.pop();
}
}
int main() {
std::thread t1(producer);
std::thread t2(consumer);
t1.join();
t2.join();
return 0;
}
```
在这个例子中,生产者线程产生数据,然后通过`cv.notify_all()`通知消费者线程。消费者线程在`cv.wait()`处等待,直到有数据可用。
四、结束语
C++多线程编程是一个深入的话题,本文只介绍了一些基础知识。在实际编程中,我们还需要考虑许多其他问题,如线程安全、数据竞争、死锁等。希望这篇文章能帮助你入门C++多线程编程,为进一步的学习打下基础。