在Linux下使用C++实现并发控制,通常会涉及到多线程编程。C++11标准库提供了<thread>
头文件,它包含了一些用于多线程编程的工具。此外,还有<mutex>
、<condition_variable>
、<future>
、<atomic>
等头文件,它们提供了同步机制,如互斥锁、条件变量、未来(用于异步操作)和原子操作。
以下是一个简单的例子,展示了如何使用C++11的线程和互斥锁来实现并发控制:
#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(); // 等待线程th1结束
th2.join(); // 等待线程th2结束
return 0;
}
在这个例子中,我们定义了一个print_block
函数,它接受两个参数:一个是要打印的字符数量n
,另一个是字符c
。在函数内部,我们使用mtx.lock()
来获取互斥锁,确保在同一时间只有一个线程可以执行打印操作。打印完成后,使用mtx.unlock()
释放锁。
在main
函数中,我们创建了两个线程th1
和th2
,它们都调用print_block
函数,但是打印不同的字符。通过调用join
方法,我们确保主线程等待这两个线程完成后再退出。
除了互斥锁,C++还提供了其他同步机制,例如:
std::lock_guard
:一个方便的RAII(Resource Acquisition Is Initialization)风格的锁管理类,它在构造时加锁,在析构时自动解锁。std::unique_lock
:一个比std::lock_guard
更灵活的锁管理类,它允许延迟锁定、时间锁定、递归锁定等。std::condition_variable
:用于线程间的等待/通知机制。std::atomic
:用于实现原子操作,保证操作的原子性,避免数据竞争。使用这些工具,你可以根据不同的场景选择合适的并发控制策略。在实际应用中,还需要注意死锁、活锁等问题,并采取相应的预防措施。