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类
  • 注意接口设计的合理性

c++11多线程记录3: 数据争用和Mutex的使用的更多相关文章

  1. c++11多线程记录2:线程管理

    线程没有调用join和detach thread对象必须调用join或者detach,否则程序会终止 例如: void func() { std::cout << "hello, ...

  2. c++11多线程记录0

    两种并发编程模型 多进程 进程间通信常用的几种方式: 文件 管道 消息队列 多线程 一个进程中存在的多个线程,通常通过共享内存来通信,(说的非常非常粗俗,就是通过类似"全局变量"的 ...

  3. c++11多线程记录6:条件变量(condition variables)

    https://www.youtube.com/watch?v=13dFggo4t_I视频地址 实例1 考虑这样一个场景:存在一个全局队列deque,线程A向deque中推入数据(写),线程B从deq ...

  4. c++11多线程记录5: Unique Lock和延时初始化

    https://www.youtube.com/user/BoQianTheProgrammer 视频网址 Unique Lock unique_lock和lock_guard类似,都是mutex的w ...

  5. c++11多线程记录4:死锁

    简单示例 举个例子,桌上有一支笔和一张纸,小A和小B都要拿到纸笔写字 小A拿了笔,小B拿了纸,这时就形成了死锁(两人都不愿意让出纸笔). 其实只要稍加控制就可以避免这种情况:规定必须先拿到纸再能去尝试 ...

  6. c++11多线程记录1 -- std::thread

    启动一个线程 话不多说,直接上代码 void func(); int main() { std::thread t(func); //这里就开始启动线程了 t.join(); // 必须调用join或 ...

  7. c++11 多线程 -- 基本使用

    c++11 多线程 – 基本使用 前言:这篇文章仅针对没有使用过c++11线程库的童鞋来高速入门,也是自己的一个简单记录,内容比較基础. 1.线程的基本使用 2.相互排斥量 3.条件变量 4.原子变量 ...

  8. C++11多线程教学(一)

    本篇教学代码可在GitHub获得:https://github.com/sol-prog/threads. 在之前的教学中,我展示了一些最新进的C++11语言内容: 1. 正则表达式(http://s ...

  9. C# 实现的多线程异步Socket数据包接收器框架

    转载自Csdn : http://blog.csdn.net/jubao_liang/article/details/4005438 几天前在博问中看到一个C# Socket问题,就想到笔者2004年 ...

随机推荐

  1. 【转载】java.util.ServiceConfigurationError: com.sun.tools.attach.spi.AttachProvider

    https://blog.csdn.net/zqz_zqz/article/details/80922164 window上运行以下代码获取jvm进程: List<VirtualMachineD ...

  2. kafk设计要点

    kafka的设计目标是高吞吐量,所以kafka自己设计了一套高性能但是不通用的协议,他是仿照AMQP( Advanced Message Queuing Protocol   高级消息队列协议)设计的 ...

  3. 59: loj #10215

    $des$ https://loj.ac/problem/10215 $sol$ exgcd检查 $code$ #include <iostream> #include <cstdl ...

  4. 集合类 collection接口 Set

    Collection接口的另外一种实现为Set集合,主要有两种实现方式一种为HashSet另一种为TreeSet,两种实现都依赖与对应的Map实现类. 代码如下: public HashSet() { ...

  5. [Beta]Scrum Meeting#3

    github 本次会议项目由PM召开,时间为5月8日晚上10点30分 时长15分钟 任务表格 人员 昨日工作 下一步工作 木鬼 撰写博客整理文档 撰写博客整理文档 swoip 改进界面 改进界面 bh ...

  6. phpstudy(小皮面板)和phpstudy2018 配置php的区别

    phpstudy(小皮面板)和phpstudy2018 配置php的区别 一.总结 一句话总结: phpstudy(小皮面板) 和 phpstudy2018 只是引入的php的位置不同,但是核心代码还 ...

  7. MySQL 性能调优

    MySQL 性能调优   索引 索引是什么 官方介绍索引是帮助MySQL高效获取数据的数据结构.笔者理解索引相当于一本书的目录,通过目录就知道要的资料在哪里,不用一页一页查阅找出需要的资料. 索引目的 ...

  8. linux中nohup 与 & 的区别

    Linux/Unix下,通常只有守护进程可在脱离终端的情况下能继续执行,而普通进程在关闭终端时会因收到SIGHUP信号(挂起信号)而退出.当终端退出后,由该终端启动的后台程序自动退出. 若想命令在后台 ...

  9. C#-关于TcpListener的AcceptTcpClient()方法造成线程阻塞,进而程序无法彻底关闭的问题

    https://blog.csdn.net/nuistchn/article/details/50809158 在<C#高级编程>第7版第24章,有提到使用TCP类. 书中写了一个实例,两 ...

  10. Shared variable in python's multiprocessing

    Shared variable in python's multiprocessing https://www.programcreek.com/python/example/58176/multip ...