C++11 多线程线程共享数据
共享数据的问题
这些在操作系统中都有详细的介绍,可以回顾操作系统课程。。很典型的就是数据竞争问题。
互斥量保护数据
最原始的方式:使用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 多线程线程共享数据相关推荐
- 多线程-非共享数据(python 版)
多线程-非共享数据 对于全局变量,在多线程中要格外小心,否则容易造成数据错乱的情况发生 1. 非全局变量是否要加锁呢? #coding=utf-8import threadingimport time ...
- [转]C++ 11 多线程--线程管理
转载地址:https://www.cnblogs.com/wangguchangqing/p/6134635.html 说到多线程编程,那么就不得不提并行和并发,多线程是实现并发(并行)的一种手段.并 ...
- C++ 11 多线程--线程管理
说到多线程编程,那么就不得不提并行和并发,多线程是实现并发(并行)的一种手段.并行是指两个或多个独立的操作同时进行.注意这里是同时进行,区别于并发,在一个时间段内执行多个操作.在单核时代,多个线程是并 ...
- C++11多线程----线程管理
说到多线程编程,那么就不得不提并行和并发,多线程是实现并发(并行)的一种手段.并行是指两个或多个独立的操作同时进行.注意这里是同时进行,区别于并发,在一个时间段内执行多个操作.在单核时代,多个线程是并 ...
- python—多线程之共享数据
多线程共享全局变量 主线程中的全局变量,作为所有子线程的共享数据 在一个进程中,至少有一个线程,这个线程就是当前进程的主线程, 执行结果: 多线程还可以共享可变的是数据类型
- [Head First Java] - 线程共享数据问题
参考 - P507 1. 说明 两个线程共享同一份数据,每次使用数据时,需要先判断其是否在合理范围 每次使用数据完毕使用Thread.sleep函数让线程阻塞 2.代码 class BankAccou ...
- 多线程之间共享数据的实现
1: 如果每个线程执行的代码相同,可以使用同一个Runnable对象,然后将共享的数据放在Runnable里面,来实现数据的共享. 例如买票系统... package com.cn.gbx;impor ...
- C++11 多线程 线程管理基础
线程管理基础 C++11 所有的线程都封装在<thread>头文件中,使用命名空间std说明. 最简单的例子: #include <iostream> #include < ...
- java 多个线程共享数据_【java并发】多个线程间共享数据
先看1个多线程间同享数据的问题: 设计4个线程,其中两个线程每次对data增加1,另外两个线程每次对data减少1. 从问题来看,很明显触及到了线程间通数据的同享,4个线程同享1个data,共同操作1 ...
最新文章
- vagrant系列教程(二):vagrant的配置文件vagrantfile详解(转)
- WaitForSingleObject的用法详细介绍
- linux 飞行模拟,为推进2020款微软飞行模拟器开发:微软启动Flight Simulator X Beta测试...
- 宣汉计算机公办学校,宣汉职业中专学校是公办的吗
- practical python and opencv_Practical Python and OpenCV + Case Studies
- linux列出管道,lsof列出的管道列表示什么意思?_linux_开发99编程知识库
- matlab区分卷积和相关
- 华为项目Tree canvas画图2
- 根据经纬度算出两个位置之间的距离
- Python 按行读取文本文件 缓存 和 非缓存实现
- ModuleNotFoundError: No module named ‘pip‘
- win7下配置IIS(ASP.net)
- java基础之测试类
- WS2811B驱动使用及使用说明应用
- Briss-最好用的pdf裁边工具
- 计算机检索系统常用的运算符,计算机信息检索过程中常用的检索表达式 计算机信息检索系统.doc...
- JAVA公司网站系统毕业设计 开题报告
- 拼多多推广位备案方法(2021.5.5)
- 信息熵与老鼠试药、称球问题
- 自己搭建云存储(WIFI路由器上接硬盘)
热门文章
- asp.net oracle 问号,ASP.NET中文变问号问题解决方案
- pytorch学习笔记(二十六):NIN
- 解决ubuntu中出现:dpkg: error processing package install-info
- [抄]人是怎么废掉的
- GitHub与Git区别,Git与SVN区别,Git国内镜像下载
- 常用的Opencv函数汇总(持续更新...)
- 【Spring Cloud】微服务和Spring Cloud
- 【Angular 4】组件生命周期钩子
- 【LINQ】Linq to SQL -- Count/Sum/Min/Max/Avg 操作符
- 跟着大彬读源码 - Redis 1 - 启动服务,程序都干了什么?