共享数据的问题

这些在操作系统中都有详细的介绍,可以回顾操作系统课程。。很典型的就是数据竞争问题。

互斥量保护数据

最原始的方式:使用std::mutex创建互斥量,使用成员lock()加锁,使用成员unlock()解锁。但是这种方式需要我们在每个函数出口都调用一次unlock(),过于繁琐。。。
实例:

// std::lock example
#include <iostream>       // std::cout
#include <thread>         // std::thread
#include <mutex>          // std::mutex, std::lockstd::mutex foo,bar;       // 全局锁void task_a () {// foo.lock(); bar.lock(); // replaced by:std::lock (foo,bar);std::cout << "task a\n";foo.unlock();bar.unlock();
}void task_b () {// bar.lock(); foo.lock(); // replaced by:std::lock (bar,foo);std::cout << "task b\n";bar.unlock();foo.unlock();
}int main ()
{std::thread th1 (task_a);std::thread th2 (task_b);th1.join();th2.join();return 0;
}
/*
输出结果:
task a
task b
*/

一般使用std::lock_guard模板类,在构造的时候对互斥量加锁,析构时解锁。

#include <iostream>
#include <mutex>
#include <thread>
#include <stdexcept>std::mutex mtx;void print_even(int x) {if(x % 2 == 0)std::cout << x << " is even\n";elsethrow (std::logic_error("not even"));
}void print_thread_id(int id) {try {std::lock_guard<std::mutex>lck(mtx);  // 函数结束时,自动析构解锁print_even(id);  // 相当于在这里加锁了} catch(std::logic_error&) {std::cout << "[exception caught]\n";}
}int main() {std::thread threads[10];for(int i = 0; i < 10; ++i) {threads[i] = std::thread(print_thread_id, i + 1);}for(auto& th : threads)th.join();
}

预防死锁

一般都是编程时候进行考虑的。。。方法留作后续补充。。操作系统上的思想为指导。

注意合理组织代码

C++中,如果是直接对地址进行操作,那么锁无法阻止这种行为。

class some_data
{int a;std::string b;
public:void do_something();
};class data_wrapper
{private:some_data data;std::mutex m;
public:template<typename Function>void process_data(Function func){std::lock_guard<std::mutex> l(m);func(data);    // 1 传递“保护”数据给用户函数}
};some_data* unprotected;void malicious_function(some_data& protected_data)
{unprotected=&protected_data;  // 这里直接获取地址,那么unprotected的操作无法被锁限制
}data_wrapper x;
void foo()
{x.process_data(malicious_function);    // 2 传递一个恶意函数unprotected->do_something();    // 3 在无保护的情况下访问保护数据
}

因此代码中尽量避免直接对临界区的数据进行地址操作。

C++11 多线程线程共享数据相关推荐

  1. 多线程-非共享数据(python 版)

    多线程-非共享数据 对于全局变量,在多线程中要格外小心,否则容易造成数据错乱的情况发生 1. 非全局变量是否要加锁呢? #coding=utf-8import threadingimport time ...

  2. [转]C++ 11 多线程--线程管理

    转载地址:https://www.cnblogs.com/wangguchangqing/p/6134635.html 说到多线程编程,那么就不得不提并行和并发,多线程是实现并发(并行)的一种手段.并 ...

  3. C++ 11 多线程--线程管理

    说到多线程编程,那么就不得不提并行和并发,多线程是实现并发(并行)的一种手段.并行是指两个或多个独立的操作同时进行.注意这里是同时进行,区别于并发,在一个时间段内执行多个操作.在单核时代,多个线程是并 ...

  4. C++11多线程----线程管理

    说到多线程编程,那么就不得不提并行和并发,多线程是实现并发(并行)的一种手段.并行是指两个或多个独立的操作同时进行.注意这里是同时进行,区别于并发,在一个时间段内执行多个操作.在单核时代,多个线程是并 ...

  5. python—多线程之共享数据

    多线程共享全局变量 主线程中的全局变量,作为所有子线程的共享数据 在一个进程中,至少有一个线程,这个线程就是当前进程的主线程, 执行结果: 多线程还可以共享可变的是数据类型

  6. [Head First Java] - 线程共享数据问题

    参考 - P507 1. 说明 两个线程共享同一份数据,每次使用数据时,需要先判断其是否在合理范围 每次使用数据完毕使用Thread.sleep函数让线程阻塞 2.代码 class BankAccou ...

  7. 多线程之间共享数据的实现

    1: 如果每个线程执行的代码相同,可以使用同一个Runnable对象,然后将共享的数据放在Runnable里面,来实现数据的共享. 例如买票系统... package com.cn.gbx;impor ...

  8. C++11 多线程 线程管理基础

    线程管理基础 C++11 所有的线程都封装在<thread>头文件中,使用命名空间std说明. 最简单的例子: #include <iostream> #include < ...

  9. java 多个线程共享数据_【java并发】多个线程间共享数据

    先看1个多线程间同享数据的问题: 设计4个线程,其中两个线程每次对data增加1,另外两个线程每次对data减少1. 从问题来看,很明显触及到了线程间通数据的同享,4个线程同享1个data,共同操作1 ...

最新文章

  1. vagrant系列教程(二):vagrant的配置文件vagrantfile详解(转)
  2. WaitForSingleObject的用法详细介绍
  3. linux 飞行模拟,为推进2020款微软飞行模拟器开发:微软启动Flight Simulator X Beta测试...
  4. 宣汉计算机公办学校,宣汉职业中专学校是公办的吗
  5. practical python and opencv_Practical Python and OpenCV + Case Studies
  6. linux列出管道,lsof列出的管道列表示什么意思?_linux_开发99编程知识库
  7. matlab区分卷积和相关
  8. 华为项目Tree canvas画图2
  9. 根据经纬度算出两个位置之间的距离
  10. Python 按行读取文本文件 缓存 和 非缓存实现
  11. ModuleNotFoundError: No module named ‘pip‘
  12. win7下配置IIS(ASP.net)
  13. java基础之测试类
  14. WS2811B驱动使用及使用说明应用
  15. Briss-最好用的pdf裁边工具
  16. 计算机检索系统常用的运算符,计算机信息检索过程中常用的检索表达式 计算机信息检索系统.doc...
  17. JAVA公司网站系统毕业设计 开题报告
  18. 拼多多推广位备案方法(2021.5.5)
  19. 信息熵与老鼠试药、称球问题
  20. 自己搭建云存储(WIFI路由器上接硬盘)

热门文章

  1. asp.net oracle 问号,ASP.NET中文变问号问题解决方案
  2. pytorch学习笔记(二十六):NIN
  3. 解决ubuntu中出现:dpkg: error processing package install-info
  4. [抄]人是怎么废掉的
  5. GitHub与Git区别,Git与SVN区别,Git国内镜像下载
  6. 常用的Opencv函数汇总(持续更新...)
  7. 【Spring Cloud】微服务和Spring Cloud
  8. 【Angular 4】组件生命周期钩子
  9. 【LINQ】Linq to SQL -- Count/Sum/Min/Max/Avg 操作符
  10. 跟着大彬读源码 - Redis 1 - 启动服务,程序都干了什么?