std::mutex
和其变体是 C++ 中用于线程同步的重要工具。让我们详细了解一下这四种互斥量的作用和使用案例:
- std::mutex:
std::mutex
是一种独占式互斥量,用于保护共享数据,确保在同一时间只有一个线程可以访问它。- 它不支持递归锁定,即同一线程不能多次锁定同一个
std::mutex
。- 不带超时功能。
- std::recursive_mutex:
std::recursive_mutex
是递归互斥量,允许同一线程多次锁定它,避免死锁。- 可重入性使得在递归函数中使用更方便。
- 不带超时功能。
-
std::timed_mutex:
std::timed_mutex
具有超时功能,可以在一段时间内尝试获取锁。- 不能递归使用,只能在不需要递归锁定的场景中使用。
-
std::recursive_timed_mutex:
std::recursive_timed_mutex
是带超时功能的递归互斥量。- 允许同一线程多次锁定,并且支持超时。
- 可以在需要递归锁定且具有超时需求的场景中使用。
下面是一个示例,展示如何使用这些互斥量:
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx; // std::mutex 示例
void worker() {
mtx.lock();
std::cout << "Thread " << std::this_thread::get_id() << " acquired the mutex." << std::endl;
mtx.unlock();
}
int main() {
std::thread t1(worker);
std::thread t2(worker);
t1.join();
t2.join();
return 0;
}
std::timed_mutex
是一种带有超时功能的互斥量,用于多线程编程。让我们看看如何使用它:
-
等待一段时间获取锁:
std::timed_mutex
允许你等待一段时间来获取锁。如果在规定的等待时间内成功获取锁,或者超时了未获取到锁,就继续执行。- 使用
try_lock_for()
成员函数来实现这一功能。
-
示例代码: 下面是一个使用
std::timed_mutex
的示例,其中我们创建了一个计数器并在多个线程中增加它:
#include <algorithm>
#include <chrono>
#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
using namespace std;
using namespace std::chrono;
volatile int counter(0); // Non-atomic counter
std::timed_mutex myMutex;
void increases10k() {
for (int i = 0; i < 10000; ++i) {
if (myMutex.try_lock_for(std::chrono::milliseconds(100))) {
++counter;
myMutex.unlock();
}
// You can add other processing logic here
}
}
int main() {
std::thread threads[10];
auto start = high_resolution_clock::now();
for (int i = 0; i < 10; ++i) {
threads[i] = std::thread(increases10k);
}
for (auto& th : threads) {
th.join();
}
std::cout << "Successfully incremented counter value: " << counter << std::endl;
auto stop = high_resolution_clock::now();
auto duration = duration_cast<microseconds>(stop - start);
cout << "函数执行时间:" << duration.count() << " 微秒" << endl;
return 0;
}
运行结果:
在上面的示例中,我们使用 try_lock_for()
来尝试获取锁。如果在规定的等待时间内成功获取锁,就会增加计数器的值。否则,线程会继续执行而不会被阻塞。