线程同步之互斥锁
- 如何使用Mutex中的lock与unlock
- try_lock、try_lock_for和try_lock_until
try_locktry_lock_fortry_lock_until
如何使用Mutex中的lock与unlock
在C++11中,您可以使用std::mutex中的lock和unlock函数来实现线程同步。lock函数用于锁定互斥量,而unlock函数用于解锁互斥量。
下面是一个简单的示例,演示了如何在C++11中使用std::mutex的lock和unlock函数:
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx; // 用于临界区的互斥量
void print_thread_id(int id) {
// 临界区(通过锁定mtx来实现对std::cout的独占访问):
mtx.lock();
std::cout << "thread #" << id << '\n';
mtx.unlock();
}
int main() {
std::thread threads[10]; // 创建10个线程
for (int i = 0; i < 10; ++i) {
threads[i] = std::thread(print_thread_id, i + 1);
}
for (auto &th : threads) {
th.join();
}
return 0;
}
/*
thread #1
thread #5
thread #3
thread #4
thread #7
thread #8
thread #9
thread #10
thread #2
thread #6
*/
try_lock、try_lock_for和try_lock_until
在C++11中,可以使用std::mutex的try_lock、try_lock_for和try_lock_until方法来尝试获取互斥锁。这些方法允许线程尝试获取锁,如果获取成功则返回true,否则返回false。
以下是使用这些方法的示例代码:
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx; // 用于临界区的互斥量
void job() {
std::cout << "begin thread # " << std::this_thread::get_id() << std::endl;
if (mtx.try_lock()) {
std::cout << std::this_thread::get_id() << " Lock acquired" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(2));
mtx.unlock();
} else {
std::cout << std::this_thread::get_id() << " Failed to acquired lock" << std::endl;
}
std::cout << "end thread # " << std::this_thread::get_id() << std::endl;;
}
int main() {
std::thread t1(job);
std::thread t2(job);
t1.join();
t2.join();
return 0;
}
/*
begin thread # 139732969322176
139732969322176 Lock acquired
begin thread # 139732960929472
139732960929472 Failed to acquired lock
end thread # 139732960929472
end thread # 139732969322176
*/
在上面的示例中,try_lock方法尝试获取互斥锁,如果获取成功则输出"Lock acquired",否则输出"Failed to acquire lock"。
另外,try_lock_for和try_lock_until方法也可以用类似的方式来使用,它们允许线程在一定时间内尝试获取锁,超时则返回false。
Mutex是一种用于多线程编程的同步原语,用于保护共享资源,以防止多个线程同时访问。在C++中,我们可以使用std::mutex来实现互斥锁。std::mutex提供了几种尝试加锁的方法,包括try_lock、try_lock_for和try_lock_until。下面我将分别介绍这三种方法的用法和作用。
try_lock
try_lock是std::mutex类的成员函数,用于尝试对互斥锁进行加锁。如果当前没有其他线程占用锁,try_lock会立即对锁进行加锁,并返回true;如果锁已经被其他线程占用,try_lock会立即返回false,而不会阻塞当前线程。
#include <mutex>
std::mutex mtx;
void example_function() {
if (mtx.try_lock()) {
// 成功获得锁
// 执行一些操作
mtx.unlock(); // 记得在操作结束后释放锁
} else {
// 未能获得锁
}
}
try_lock_for
try_lock_for是std::mutex类的成员函数,用于尝试在指定的时间段内对互斥锁进行加锁。如果在指定时间内获得了锁,函数返回true;如果在指定时间内未获得锁,函数返回false。
#include <mutex>
#include <chrono>
std::mutex mtx;
void example_function() {
if (mtx.try_lock_for(std::chrono::milliseconds(100))) {
// 成功获得锁
// 执行一些操作
mtx.unlock(); // 记得在操作结束后释放锁
} else {
// 未能在100毫秒内获得锁
}
}
try_lock_until
try_lock_until是std::mutex类的成员函数,用于尝试在指定的时间点之前对互斥锁进行加锁。如果在指定时间点之前获得了锁,函数返回true;如果在指定时间点之前未获得锁,函数返回false。
#include <mutex>
#include <chrono>
std::mutex mtx;
void example_function() {
auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(1000);
if (mtx.try_lock_until(timeout)) {
// 成功获得锁
// 执行一些操作
mtx.unlock(); // 记得在操作结束后释放锁
} else {
// 未能在指定时间点之前获得锁
}
}
这些方法可以帮助我们在多线程编程中更灵活地管理互斥锁,避免线程阻塞和死锁的问题。