博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++11: Multi-Thread思考.
阅读量:7043 次
发布时间:2019-06-28

本文共 1683 字,大约阅读时间需要 5 分钟。

hot3.png

使用多线程几乎总是伴随着"数据的并发访问",多个线程之间毫无干系的并行运行是很罕见的。线程有可能提供数据给其他线程处理,或者是备妥必要条件(比如shared state)用以供其它线程使用,或者是供其它线程ublock.

首先我们要明确的是自C++11起:不同的对象拥有各自的内存区.

Concurrent Data Access为什么会造成问题?

1,Unsynchronized data access(未同步化的数据访问):并行运行的两个线程读写同一个内存中的数据,不知道哪个语句先来.

2,Haft-written data(写至半的数据):某个线程正在读该内存中的数据,另一个线程则尝试改动它。

3,Reordered statement(重新安排的语句):语句和操作由于编译器的优化被重新安排执行的次序,甚至不自行,也许对于一个单线程的程序是没有问题的,但是对于多线程的组合却破坏了预期的行为.

Unasynchronized Data Access:

if(val >=0 ){  //间隙1  f(val);}else{  //间隙2  f(-val);}

在单线程的环境中上述代码是没有任何问题的,但是在多线程的环境中,如果多个线程处理val的值,也就是说val的值在间隙1和间隙2处被改变!!!!!!这样不就超出我们的预期了么.

std::vector
v;....if(!v.empty()){ //间隙. std::cout<< v.front() << std::endl;}

在单线程的环境中上述的代码也是没问题的,但是在多线程的环境中很有可能在间隙处v变成empty.

Half-Written Data(写至半途而废的数据):

考虑我们有一个变量:

long long x = 0;

某个线程对它写入数值:

x = -1;

另外一个线程读取它:

std::cout << x;

程序的输出是什么?也就是说当另外一个线程读取它的时候可能是:

1, 0(x的旧值)-如果第一个线程尚未赋予她-1;

2,-1(x的新值) -如果第一线程已经赋予了它-1;

3,任何其他值-如果在第一个线程对x赋予-1的过程中.

不仅仅是上面我们所举例的long long类型、即使基本数据类型如int和bool,标准也不保证读写是atomic(不可切割的,意思是独占的不可被打断的,也就是说读的时候是一定不能被写的)。

Reordered Statement(重新安排的语句):

假设有两个共享对象,一个是long类型用来将data从某个线程传递到另一个线程,另外一个是bool readyFlag,用来表示第一个线程是否已经提供了数据.

long data;bool readyFlag = false;

一般都会想到,将“某线程中对data的设定”和“另外一个线程中队data的销毁”同步化(synchronize),于是写出下面的代码.

//线程1data = 42;readyFlag = ture;
//线程2while(!readyFlag){   ;}foo(data);

在不知道任何细节的情况下,几乎一开始都会认为线程2的foo()函数肯定是在data有值42之后才会被调用的。认为对foo()的调用只有在readyFlag为ture的前提下才能触及,而为ture又发生在42赋值给data之后,因为赋值之后才令readyFlag为ture.

但是事实并非如此编译器优化过后可能重新安排语句:

readyFlag = ture;data = 42;

 

解决以上问题所需要的性质:

Atomicity(不可切割性):这意味着读写一个变量其行为都是独占的,排他的,无任何打断的,因此一个线程不可能读到“因另外一个线程而造成的”中间状态.

Order(次序):我们需要一些方法保证“某些具体指定语句”的次序.

 

转载于:https://my.oschina.net/SHIHUAMarryMe/blog/677289

你可能感兴趣的文章
php过滤提交数据 防止sql注入***(6)
查看>>
flv视频网站制作 使用Flex和PHP创建自己的视频应用
查看>>
autofs常见错误
查看>>
【OCP-12c】2019年CUUG OCP 071考试题库(79题)
查看>>
[Redis常用命令]
查看>>
小白把CentOS6.8安装在移动硬盘中
查看>>
控制线程
查看>>
oracle12c 高负载进程
查看>>
随时随地掌上邮,飞邮Android版邮件客户端正式提供试用
查看>>
atom的插件必备
查看>>
MySQL引擎特性GIS-R-TREE
查看>>
elasticsearch优化及查询api
查看>>
日志系统syslog
查看>>
使用curator删除es索引
查看>>
storm入门
查看>>
Cisco网络设备之2950交换机详解篇
查看>>
从“比较两个含有多个不同元素的集合是否相同”引申出的几种算法
查看>>
第2章 命令工具
查看>>
smbpasswd
查看>>
python 多进程、多线程、协程
查看>>