💻线程锁的介绍
顾名思义,线程锁一般用在多线程中。当多个线程运行,并共享了同一块资源,在访问这块资源的时候就称为临界资源。为了解决这个问题,我们可以为这块资源加上一把锁,只允许一个线程访问这块资源。即,锁用来在多线程访问同一个资源时防止数据竞险,保证数据的一致性访问。
多线程本来就是为了提高效率和响应速度,但锁的使用又限制了多线程的并行执行,这会降低效率,但为了保证数据正确,不得不使用锁,它们就是这样纠缠。
线程之间的锁有:互斥锁、条件锁、自旋锁、读写锁、递归锁。一般而言,锁的功能与性能成反比。不过我们一般不使用递归锁(C++标准库提供了std::recursive_mutex),所以这里就不推荐了。
📱互斥锁(Mutex)
互斥锁用于控制多个线程对他们之间共享资源互斥访问的一个信号量。也就是说是为了避免多个线程在某一时刻同时操作一个共享资源。例如线程池中的有多个空闲线程和一个任务队列。任何是一个线程都要使用互斥锁互斥访问任务队列,以避免多个线程同时访问任务队列以发生错乱。
在某一时刻,只有一个线程可以获取互斥锁,在释放互斥锁之前其他线程都不能获取该互斥锁。如果其他线程想要获取这个互斥锁,那么这个线程只能以阻塞方式进行等待。
头文件:#include < mutex>
类型: std::mutex
用法: 在C++中,通过构造std::mutex的实例创建互斥元,调用成员函数lock()来锁定它,调用unlock()来解锁,不过一般不推荐这种做法,C++11中引入了std::unique_lock与std::lock_guard两种数据结构,实现了互斥元的RAII惯用语法。std::mutex和std::unique_lock、std::lock_guard。都声明在< mutex >头文件中。
参考代码:
//用互斥元保护列表 #include <list> #include <mutex> std::list<int> some_list; std::mutex m_mutex; //unique_lock void add_to_list(int new_value) { std::unique_lock<std::mutex> lock(m_mutex); some_list.push_back(new_value); } //lock_guard void add_to_list(int new_value) { std::lock_guard<std::mutex> guard(m_mutex); some_list.push_back(new_value); }
std::unique_lock和std::lock_guard类的区别:
std::unique_lock 与std::lock_guard都能实现自动加锁与解锁功能,但是std::unique_lock要比std::lock_guard更灵活,但是更灵活的代价是占用空间相对更大一点且相对更慢一点。
更详细的对比参考:C++11中的lock_guard和unique_lock使用浅析
参考:C++11线程中的几种锁
戳戳小手帮忙点个免费的赞和关注吧,嘿嘿。 |