php 手机网站cms系统,木兰网,vueseo解决方案,怎样申请一个免费网站目录
普通互斥锁#xff1a;
轻量级锁
独占锁#xff1a;
std::lock_guard#xff1a;
std::unique_lock:
共享锁#xff1a;
超时的互斥锁
递归锁 普通互斥锁#xff1a;
std::mutex确保任意时刻只有一个线程可以访问共享资源#xff0c;在多线程中常用于保…目录
普通互斥锁
轻量级锁
独占锁
std::lock_guard
std::unique_lock:
共享锁
超时的互斥锁
递归锁 普通互斥锁
std::mutex确保任意时刻只有一个线程可以访问共享资源在多线程中常用于保护共享资源。
互斥锁的实现示例
#include iostream
#include thread
#include mutexstd::mutex Mutex;
int shared_source 1;void Shared_data()
{//获取锁Mutex.lock();shared_source;std::cout shared_source : shared_source by thread :std::this_thread::get_id() std::endl;//锁释放Mutex.unlock();
}
int main()
{std::thread thread1(Shared_data);std::thread thread2(Shared_data);thread1.join();thread2.join();return 0;
}
在实际使用的过程中如果容易忘记对锁进行释放可以使用std::unique_lock和std::lock_guard安全的管理锁的释放。
轻量级锁
在C中轻量级锁通常指的是一些开销较小性能较高的锁机制C并没有直接提供“轻量级锁”的概念可以通过一个自旋锁来达到实现轻量级锁的目的。
适用场景竞争不激烈比如在大多数时间里中有一个线程需要访问临界区的情况。但如果竞争激烈会导致CUP资源的浪费CPU自旋降低性能。
自旋锁一种简单的锁机制当线程尝试获取锁时如果锁已被其他线程占用则当前线程会不断地循环等待直到锁可用
自旋锁的示例
#include iostream
#include thread
#include atomicstd::atomicboolspinlock(false);void spin_lock()
{while (spinlock.exchange(true, std::memory_order_acquire)){//如果锁被占用则一直自旋等待锁可用}
}void spin_unlock()
{spinlock.store(false, std::memory_order_release);//释放锁并将锁的状态写入内存中
}
void critical_section()
{spin_lock();std::cout mutex acquire by thread : std::this_thread::get_id() std::endl;
// std::this_thread::sleep_for(std::chrono::seconds(1));spin_unlock();//锁释放
}
int main()
{std::thread t1(critical_section);std::thread t2(critical_section);t1.join();t2.join();return 0;
}
独占锁
std::unique_lock和std::lock_guard都是cpp标准库提供的管理互斥锁的类他们都提供了自动锁和解锁的功能。但二者存在一些关键区别
std::lock_guard
std::lock_guard并不是一种锁而是一个作用域锁管理一个能管理锁生命周期的工具用于简化互斥锁的使用确保在作用域结束后自动释放锁避免死锁问题自动加锁和解锁在构造时自动加锁在析构时自动解锁不需要显示的调用加锁和解锁的方法不支持条件变量配合使用条件变量需要可以临时释放锁并重新获取锁但是lock_guard并没有提供unlock().使用场景适用于不需要显示控制加锁和解锁的场景或者不需要与条件变量配合使用的场景适用于在某个作用域中同步访问共享资源的场景
lock_guard示例
#include iostream
#include thread
#include mutexstd::mutex mtx;
int shared_data 0;void worker()
{std::lock_guardstd::mutexlock(mtx);//自动加锁shared_data;std::cout shared_data by thread : std::this_thread::get_id() std::endl;//自动解锁无需显示调用unlock()
}
int main()
{std::thread t1(worker);std::thread t2(worker);t1.join();t2.join();return 0;
}
std::unique_lock:
std::unique_lock本身不是一种锁而是一个可选的互斥锁管理器提供了对互斥锁的更加灵活的控制方式显示加锁和解锁提供了lock()和unlock()方法可以显示的加锁和解锁也可以在构造时自动加锁可以与条件变量配合自动管理锁的生命周期避免了因忘记解锁而导致的死锁问题使用场景需要显示控制加锁和解锁时机或者需要和条件变量配合使用的场景
unique_lock实例
#include iostream
#include thread
#include mutexstd::mutex mtx;
int shared_data 0;
char str a;//不显示调用加解锁自动加锁和解锁
void worker()
{std::unique_lockstd::mutexlock(mtx);//defer_lock 延迟锁定操作需要在特定的时机才锁定互斥锁shared_data 1;std::cout shared_data : shared_data ,by thread : std::this_thread::get_id() std::endl;std::cout str: str ,by thread: std::this_thread::get_id() std::endl;}
//显示调用加锁和解锁
void worker()
{std::unique_lockstd::mutexlock(mtx,std::defer_lock);//defer_lock 延迟锁定操作需要在特定的时机才锁定互斥锁shared_data1;std::cout shared_data :shared_data ,by thread : std::this_thread::get_id() std::endl;lock.lock();//延迟锁定std::cout str: str ,by thread: std::this_thread::get_id() std::endl;lock.unlock();//显示解锁
}int main()
{std::thread t1(worker);std::thread t2(worker);t1.join();t2.join();return 0;
}
独占锁与mutex相比更加的安全它可以避免忘记手动解锁会在其作用域结束时自动的释放锁
共享锁
在C中共享锁允许多个线程共享读取资源但在写入资源时只允许一个线程写入数据要求独占锁。当某个线程获取了独占锁时其他线程无法获取任何形式地锁而当多个线程获取共享锁时他们可以同时读取共享资源
使用场景适用于读多写少的场景下能有效提高多线程程序的性能
示例
#include iostream
#include thread
#include shared_mutexstd::shared_mutex mtx;
int shared_data 0;
void read_data()
{//获取共享锁std::shared_lock std::shared_mutex lock(mtx);std::cout Reading data : shared_data std::endl;
}
void write_data()
{//获取独占锁std::unique_lockstd::shared_mutexlock(mtx);shared_data 24;std::cout Writing data : shared_data std::endl;
}
int main()
{std::thread t1(read_data);std::thread t2(read_data);std::thread t3(write_data);t1.join();t2.join();t3.join();return 0;
}
超时的互斥锁
C标准库提供了timed_mutex来实现该功能支持超时机制当线程尝试获取锁时可以指定一个超时时间如果在该时间内无法获取锁线程将返回并继续执行其他任务。通过使用超时互斥锁可以有效的避免线程在等待锁时无限地阻塞提高程序地响应和稳定性
示例
#include iostream
#include thread
#include mutex
#include chrono//超时锁
//C标准库提供的互斥锁之一支持在尝试获取锁时设置超时时间
std::timed_mutex mtx;void function_time()
{//在1s内获取锁//try_lock_for在指定时间内获取锁成功返回true失败则false//参数chrono是一个时间间隔类型的一个域if (mtx.try_lock_for(std::chrono::seconds(1))){std::cout Lock acquired std::endl;//模拟耗时操作//在当前线程休眠这2s内其他线程无法获取该锁//所以当t2尝试获取锁时t1持有锁并休眠2s当锁释放后t2锁获取超时std::this_thread::sleep_for(std::chrono::seconds(2));mtx.unlock();//释放锁}else{std::cout Fail to acquire lock within 1s std::endl;}
}
int main()
{//主线程创建的这俩线程几乎同时开始执行function_time函数std::thread t1(function_time);std::thread t2(function_time);t1.join();t2.join();return 0;
}
递归锁
递归锁同一个线程多次获取同一把锁而不会导致死锁。cpp中没有直接提供递归锁的实现但是可以通过reecursive_mutex来实现递归锁的功能。
reecursive_mutex一个可重入的互斥锁允许同一个线程多次调用lock或try_lock来获取锁不会导致死锁。
使用场景需要在同一个线程中多次获取锁的场景
递归锁示例
#include iostream
#include thread
#include mutexstd::recursive_mutex mtx;void function(int n)//递归
{if (n 0){mtx.lock();std::cout lock acquired by thread : std::this_thread::get_id() n ; n std::endl;function(n - 1);mtx.unlock();}}int main()
{std::thread t1(function,3);std::thread t2(function,2);t1.join();t2.join();return 0;
}