方法一:
强行将共享资源变成非共享的资源(如果没有必要的话,线程间不要共享资源),这样效率高,速度快,编程难度低,不易出错,能使用则使用
方法二:
在必须共享时候,使用原子操作。
使用的头文件 将寄存器三步操作连续完成
一般的基本类型操作,使用该库都能完成,如++ – + * /
,专家级别的fetch_add fetch_sub
代码演示
修改之前博客中的Counter即可
class Counter
{
public:
void addCount(){m_count++;}
int count()const{return m_count;}
Counter():m_count{0}{}
private:
std::atomic<int>m_count;
//std::atomic_int m_count
}
打印结果
class Counter
{
public:
void addCount(){m_count++;}
int count()const{return m_count;}
void addResouce(int r){m_totalResouce++;}
int aveResource()
{
if(m_count == 0)
return 0;
return m_totalResouce/m_count;
}
Counter():m_count{0},m_totalResouce{0}{}
private:
std::atomic<int>m_count;
std::atomic<int>m_totalResouce;
//std::atomic_int m_count
}
局限性:
在测试中 m_count 与m_totalResouce 同时加一但是商却不恒等于1,但在二者都完成所有次数之后商为1
原因:虽然atomic 定义的变量本身为原子变量,但是两个原子变量可能在不同的线程中进行运算造成错误 ,原理上与非原子变量进行运算时造成运算错误一样
方法三:
使用库的锁的方式
class Counter
{
public:
void addCount(){m_count++;}
int count()const{return m_count;}
void addResouce(int r){m_totalResouce++;}
int aveResource()
{
if(m_count == 0)
return 0;
return m_totalResouce/m_count;
}
Counter():m_count{0},m_totalResouce{0}{}
void lockMutex(){m_mutex.lock()};
void unlockMutex(){m_mutex.unlock()};
private:
std::atomic<int>m_count;
std::atomic<int>m_totalResouce;
//std::atomic_int m_count
std::mutex m_mutex;
}