文章目录
(一) 线程概念、创建及传参
(二) 独占互斥锁–mutex,lock_guardy与其他mutex
(三) unique_lock替换lock_guardy
(四) 单例模式(Singleton)下的线程安全问题
(五) window临界区
(六) condition_variable条件变量
(七) std::async异步任务与std::future< >
(八) packaged_task< >与promise< >
(九) 原子操作atomic<>简介
(1)简介
- 不同的操作系统有不同的API,使用方式不同,即不可跨平台
- 而在C++中使用的多线程接口函数都从语言本身,而不是操作系统,即可跨平台
- 简单了解一些Windows的临界区涨知识
(2)使用方法
1.进入临界区相当于加锁
2.可多次进入临界区
3.进入几次临界区就要调通几次离开临界区函数,否则死锁
- 先定义临界区变量
CRITICAL_SECTION m_winCritical; //1.定义一个临界区成员变量
- 初始化
//2.初始化临界区变量
InitializeCriticalSection(&m_winCritical);
- 进入与离开
EnterCriticalSection(&m_winCritical); //进入临界区
EnterCriticalSection(&m_winCritical);//可进入多次
//...
//操作共享数据
//...
LeaveCriticalSection(&m_winCritical);//离开临界区
LeaveCriticalSection(&m_winCritical);//也要离开多次
(3)自定义自动解锁类
class uniLockWins { //自动解锁临界区
private:
CRITICAL_SECTION* _critical_sec;
public:
uniLockWins(CRITICAL_SECTION* sec) {
_critical_sec = sec;
EnterCriticalSection(_critical_sec);
}
~uniLockWins() { LeaveCriticalSection(_critical_sec); }
};
- 测试代码
#include <iostream>
#include<thread>
#include<windows.h>
#include<list>
using namespace std;
class uniLockWins { //自动解锁临界区
private:
CRITICAL_SECTION* _critical_sec;
public:
uniLockWins(CRITICAL_SECTION* sec) {
_critical_sec = sec;
EnterCriticalSection(_critical_sec);
}
~uniLockWins() { LeaveCriticalSection(_critical_sec); }
};
class CReadAndWrite
{
public:
CReadAndWrite() {
//2.初始化临界区变量
InitializeCriticalSection(&m_winCritical);
};
void read();
void wirte();
private:
list<int> m_list;
CRITICAL_SECTION m_winCritical; //1.定义一个临界区成员变量
};
void CReadAndWrite::wirte()
{
for (int i = 0; i < 1000; i++)
{
//EnterCriticalSection(&m_winCritical);//进入临界区
uniLockWins autolock1(&m_winCritical); //使用自动解锁
uniLockWins autolock2(&m_winCritical); //也可多次调用
m_list.push_back(i);
//LeaveCriticalSection(&m_winCritical);//离开临界区
cout << "write " << i << endl;
}
}
void CReadAndWrite::read()
{
for (int i = 0; i < 100000; i++)
{
if (m_list.size())
{
EnterCriticalSection(&m_winCritical); //进入临界区
EnterCriticalSection(&m_winCritical);//可进入多次
int num = m_list.front();
m_list.pop_front();
LeaveCriticalSection(&m_winCritical);//离开临界区
LeaveCriticalSection(&m_winCritical);//也要离开多次
cout << "输出 num = " << num << endl;
}
}
}
int main()
{
CReadAndWrite obj;
thread mywrite(&CReadAndWrite::wirte, &obj);
thread myread(&CReadAndWrite::read, &obj);
mywrite.join();
myread.join();
std::cout << "主函数结束\n";
}