https://www.youtube.com/watch?v=3ZxZPeXPaM4 学习视频

数据争用

简单来说就是存在多个线程同时对某个共同的对象进行读写(至少有一个线程在做写操作),造成读取这个对象时的结果不可预测

如下

int num = 0;

void func(int &v)
{
for (int i = 0; i < 100000; ++i)
{
num = num + 1;
v++;
}
} int main()
{
int v = 0;
std::vector<std::thread> ts;
for (int i = 0; i < 100; ++i)
{
ts.push_back(std::thread(func, std::ref(v)));
} for (int i = 0; i < 100; ++i)
{
ts[i].join();
} std::cout << num << ", " << v << std::endl;
return 0;
}

cout结果并不是10 000 000, 10 000 000

使用Mutex控制对象的读写

在对象的读写操作之前调用mutex::lock即可(记得不需要持有对象时调用mutex::unlock)

...
std::mutex mu;
void func()
{
...
mu.lock();
num += 1;
v += 1;
mu.unlock();
}
...

std::lock_guard

在mutex的lock-unlock块里如果抛出异常,那么unlock就不会被调用(或者忘记调用unlock也是有可能的),

这时可以考虑使用lock_guard:

...
{
std::lock_guard<std::mutex> guard(mu);
v++;
num++;
}
...

我感觉应该是lock_guard内部将会持有mutex,然后在析构函数里尝试调用mutex的unlock方法

读写控制的对象有没有完全被锁定

针对上面的例子,有一个全局变量num,和一个局部变量v,虽然在各个子线程里都用mutex进行了读写控制;

但是在主线程里并没有,仍然可以在main里面随意的处理这两个共享对象;

处理方法就是将要保护的资源对象和mutex绑定在一起,保证每次使用资源对象前必须通过mutex

如下:

class LogFile {
std::mutex m_mutex;
ofstream f;
LogFile() {
f.open(...);
}
void shared_print(string id, int value) {
std::lock_guard<mutex> guard(m_mutex);
f << id << ", " << value << endl;
}
// ofstream &getStream() { return f; }
}

上面这个例子,切记不能将LogFile的f对象暴露出来,就像最后一行注释那样

当然如果返回的是ofstream是没问题的;

还有一些其它情况可能“意外”暴露LogFile::f,如下:

void LogFile::processf(void fun(ofstream&))
{
fun(this->f);
}

这里就“不小心”将f对象引用传递给了某个函数fun,在fun里,LogFile::f就失去了mutex的保护

小结

  • 使用mutex来控制资源对象的读写
  • 不要将内部资源对象暴露出Wrapper类
  • 注意接口设计的合理性

最新文章

  1. OpenFlow:Enabling Innovation in Campus Networks
  2. signalR制作微信墙 开源
  3. 使用friso中文分词注意
  4. C#委托的异步调用
  5. JSOI2015 R3 退队滚粗了
  6. DevExpress 控件使用之XtraReport
  7. http://blog.csdn.net/baimafujinji/article/details/10931621
  8. vue实例的生命周期
  9. 【XSY1602】安全网络 树形DP 数学
  10. 如何在Mac上安全彻底的卸载软件?
  11. ajax后台输出有红点
  12. Oozie分布式工作流——从理论和实践分析使用节点间的参数传递
  13. mysql/mariadb应该使用utf8mb4而不是utf8
  14. .net 高并发 多消费者模式处理订单
  15. 如何控制iOS的导航栏和状态栏的样式
  16. 普天通信JavaEE开发岗面试题
  17. Http缓存知识;HTTPS, HTTP2相关知识;百度统计和即时线上客服。
  18. 十分有趣的this指向题
  19. IEEEXtreme 10.0 - Counting Molecules
  20. Flexigrid-Web2.0 jQuery

热门文章

  1. maven的安装、路径配置、修改库文件路径和eclipse中的配置、创建maven工程。
  2. Python回归分析五部曲(一)—简单线性回归
  3. gcc 编译c++文件
  4. HDU 6212 Zuma
  5. prometheus(docker)安装和报警 -- nginx域名监控
  6. 是什么让我走上Java之路?
  7. SpringAOP ApectJ 动态代理
  8. Ubuntu 17.10安装VirtualBox 5.2.2 及相关问题解决
  9. pdf 中画虚线
  10. 【maven】maven下载依赖jar的源码