文章目录
(一) 线程概念、创建及传参
(二) 独占互斥锁–mutex,lock_guardy与其他mutex
(三) unique_lock替换lock_guardy
(四) 单例模式(Singleton)下的线程安全问题
(五) window临界区
(六) condition_variable条件变量
(七) std::async异步任务与std::future< >
(八) packaged_task< >与promise< >
(九) 原子操作atomic<>简介
(1)unique_lock 类模板
1.unique_lock更灵活,但效率比lock_guard低一点,占用内存多一些
2.第二参数传入 std::adop_lock ,与lock_guard一样使用前必须先lock
3.第二参数传入 std::try_to_lock,拿到锁才进行,不产生堵塞,使用前不能lock
4.第二参数传入 std::defer_lock,使用前不能lock,创建后自己加锁,可以自行lock与unlock最后析构也会自动解锁
5.release()释放mutex所有权,释放后需手动ublock
6.转交所有权需用 std::move()函数,同智能指针unique_ptr
7.也可使用函数 return std::unique_lockstd::mutex 返回局部对象系统调用移动构造函数
- 参数adop_lock 使用方法同lock_guard
std::mutex m_mutex;
m_mutex.lock()
std::unique_lock<mutex> l1(m_mutex,std::adopt_lock); //使用前必须lock,代替lock_guard,创建后没解锁不能再上锁
//...
//操作共享数据
//...
unique_lock.unlock() //可提前解锁
//...
//非共享代码....
//...
unilock.lock(); //灵活使用,提高粒度,自动解锁
//可使用unlock提前解锁,也可不用自动解锁
//但注意不能重复解锁或上锁
- 参数try_to_lock不会堵塞
std::unique_lock<mutex> getlock(m_mutex,std::try_to_lock); //使用前不能上锁
if (getlock.owns_lock())
{
//操作共享数据代码...
}
else
{
cout << "不堵塞~~~没有拿到锁~~~~"<< endl;
}
- 参数defer_lock需要自行上锁
std::unique_lock<mutex> unilock(m_mutex1, std::defer_lock);
unilock.lock(); //若不锁则崩
m_list.push_back(i);
cout << "write " << i << endl;
unilock.unlock();
//非共享代码....
unilock.lock(); //灵活使用,提高粒度,自动解锁
//...
unilock.unlock();
- release释放绑定,返回指针
- 见代码段
- 测试代码
#include <iostream>
#include<thread>
#include<mutex>
#include<list>
using namespace std;
class CReadAndWrite
{
public:
CReadAndWrite() {};
void read();
void wirte();
private:
list<int> m_list;
mutex m_mutex1;
mutex m_mutex2;
};
void CReadAndWrite::wirte()
{
for (int i = 0; i < 100; i++)
{
//m_mutex1.lock();
//std::unique_lock<mutex> l1(m_mutex1,std::adopt_lock); //使用前必须lock,代替lock_guard
std::unique_lock<mutex> unilock(m_mutex1, std::defer_lock);
unilock.lock();
m_list.push_back(i);
cout << "write " << i << endl;
unilock.unlock();
//非共享代码....
unilock.lock(); //灵活使用,提高粒度,自动解锁
std::mutex* mut = unilock.release(); //释放绑定,返回指针
mut->unlock(); //若已上锁,需自行解锁,否则崩溃
}
}
void CReadAndWrite::read()
{
for (int i = 0; i < 100; i++)
{
if (m_list.size())
{
std::unique_lock<mutex> unilock(m_mutex1, std::try_to_lock); //使用前不能lock
std::unique_lock<mutex> getlock(std::move(unilock)); //转交所有权用move
if (getlock.owns_lock())
{
int num = m_list.front();
cout << "输出 num = " << num << endl;
m_list.pop_front();
}
else
{
cout << "不堵塞~~~没有拿到锁~~~~"<< endl;
}
}
else
cout << "空~~~~" << endl;
}
}
int main()
{
CReadAndWrite obj;
thread mywrite(&CReadAndWrite::wirte, &obj);
thread myread(&CReadAndWrite::read, &obj);
mywrite.join();
myread.join();
std::cout << "Hello World!\n";
}