并发数据结构-1.1 并发的数据结构的设计

原文链接,译文链接,译者:董明鑫,校对:周可人

随着多个处理器共享同一内存的机器在商业上的广泛使用,并发编程的艺术也产生了巨大的变化。当前的趋势向着低功耗芯片级多线程(CMT)发展,所以这样的机器一定会更加广泛的被使用。

共享内存多处理器是指并发的执行多个线程的系统,这些线程在共享的内存中通过数据结构通讯和同步。这些数据结构的效率对于性能是很关键的,而目前熟练掌握为多处理器机器设计高效数据结构这一技术的人并不多。对大多数人来说,设计并发的数据结构比设计单线程的难多了,因为并发执行的线程可能会多种方式地交错运行他们的指令,每一种方式会带来不同的,甚至不符合预期的输出。这就要求设计者改变他们对运算的认识,理解新的设计方法,采用新的编程工具集。此外,设计可扩展的并发数据结构,使得当机器执行越来越多的并发线程时依旧表现良好也是新的挑战。本文主要介绍设计并发数据结构的相关挑战,和一些重要的数据结构相关内容的总结。我们的总结绝不是全面的;相反,我们特意选取了一些能说明设计的关键问题的流行的数据结构,希望我们提供了足够的背景和知识,让有兴趣的读者接触那些我们没有提到的内容。

1.1 并发的数据结构的设计

共享内存多处理器的一些特性使得并发数据结构的设计和校验比相对应的单线程结构难度显著增加。

acquire(Lock);

oldval = X;                                                                                      oldval = X;

X = oldval + 1;                                                                                X = oldval + 1;

return oldval;                                                                                 release(Lock);

return oldval;

图1.1:顺序的和基于锁机制的fetch-and-inc操作代码片段

难点的根源在于并发:因为线程是在不同的处理器上并发的执行,而且受操作系统的调度决策、缺页、中断等等影响,我们必须按照全部异步的想法来思考,以保证不同的线程能够随意交错的运行。这显著提升了正确设计并发数据结构的复杂度。

为多处理器系统设计并发的数据结构在性能和可扩展性上也有大量的挑战。在现代的机器上,处理器和内存的布局、数据在内存中的布局、多处理器体系结构中各个元素间的通信负载全都对性能有影响。此外,正确性和性能两者联系非常的紧密:算法的改进在提高性能的同时经常使其更加难以设计和检验正确的数据结构实现。

下面的例子阐述了影响数据结构设计的各个多处理器特征。假设我们想要实现一个共享的计数器数据结构,用于支持fetch-and-inc操作,即计数器加一然后返回增加前的值。一个普通的顺序fetch-and-inc实现的代码就如图1.1中左边部分所展示的那样。

如果我们允许多个线程并发地调用fetch-and-inc操作,上述实现运行起来并不正确。来看看原因,注意大多数编译器会把这份源代码转换成机器指令:把 X 的值装进一个寄存器,然后把寄存器中的值加一,然后再把这个寄存器的值存回 X 。假如计数器初始化为 0 ,两个不同的处理器并发的执行两个fetch-and-inc操作。然后就有可能两个操作都从 X 中读出 0 ,然后都把 1 存回 X 并且返回 0 。这显然是不正确的:两个操作中有一个应该返回 1 。

如上所述,两个fetch-and-inc操作不正确的交错结果导致了不正确的行为。一个自然并且普通的方法来阻止这样的交错就是用互斥锁(也被叫做 mutex 或者 lock)。锁是一个在任意时间点,都是不被(其他线程)获取,只被一个线程所获取的构造。如果一个线程 t1 希望获取已经被另一个线程 t2 所获取到的锁,那么 t1 必须等到 t2 释放这个锁。

如图 1.1 右半部分所示,我们能通过锁机制得到一个正确的顺序实现。我们通过阻止所有的交错来预防坏的交错。这样很容易得到一个正确的共享计数器,然而这种简单是有代价的:锁机制引发了许多关于性能和软件工程上的问题。


文章转自 并发编程网-ifeve.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/541340.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

printstream_Java PrintStream close()方法与示例

printstreamPrintStream类close()方法 (PrintStream Class close() method) close() method is available in java.io package. close()方法在java.io包中可用。 close() method is used to close the underlying output stream. close()方法用于关闭基础输出流。 close() meth…

oracle底层执行顺序,select语句结构与执行顺序-Oracle

select语句结构与执行顺序select语句的结构与执行顺序,下面的序号代表执行顺序8 SELECT (9)DISTINCT11 1 ROM 3   JOIN 2   ON 4 WHERE 5 GROUP BY 6 WITH {CUBE | ROLLUP}7 HAVING 10 ORDER BY 补…

HDU 4923 Room and Moor(瞎搞题)

瞎搞题啊。找出1 1 0 0这样的序列,然后存起来,这样的情况下最好的选择是1的个数除以这段的总和。然后从前向后扫一遍。变扫边进行合并。每次合并。合并的是他的前驱。这样到最后从t-1找出的那条链就是最后满足条件的数的大小。Room and Moor Time Limit:…

java define_Java Long类的define()方法与示例

java define长类解码()方法 (Long class decode() method) decode() method is available in java.lang package. 在java.lang包中提供了define ()方法 。 decode() method is used to decode the given String value into a Long value. encode()方法用于将给定的String值解码…

linux修改文件用户组,linux命令 修改文件、文件夹所属用户、用户组

最近学习hadoop,在替换配置文件的时候,发现老是报错,没有权限替换。我们知道如何改变文件的用户组与拥有者了,那么,什么时候要使用chown或chgrp呢?或许你会觉得奇怪吧?是的,确实有时…

Kotlin 开篇

Kotlin 是一个基于 JVM 的新的编程语言,由 JetBrains 开发官网地址:http://kotlinlang.org。JetBrains,作为目前广受欢迎的 Java IDE IntelliJ 的提供商,在 Apache 许可下已经开源其Kotlin 编程语言。开源地址:https:/…

inputstream示例_Java InputStream close()方法与示例

inputstream示例InputStream类close()方法 (InputStream Class close() method) close() method is available in java.io package. close()方法在java.io包中可用。 close() method is used to close this InputStream and free all system resources linked with this stream…

linux下的文件系统,Linux根文件系统(“/”文件系统)下的目录介绍

Linux下的文件存储与Windows完全不同,Windows将系统文件存储在系统盘(比如说C:\下)Linux根本没有盘符到概念只有一个根文件系/,各个磁盘分区挂载在/media/下(或者/mnt/下)/下到如/etc,/proc,/bin,/dev,lib等很是让用惯了Windows的用户不解,下…

greenlet 详解

greenlet初体验回到顶部Greenlet是python的一个C扩展,来源于Stackless python,旨在提供可自行调度的‘微线程’, 即协程。generator实现的协程在yield value时只能将value返回给调用者(caller)。 而在greenlet中,target.switch&am…

Java Calendar toString()方法与示例

日历类toString()方法 (Calendar Class toString() method) toString() method is available in java.util package. toString()方法在java.util包中可用。 toString() method is used to string denotations of the calendar object. toString()方法用于对日历对象的符号进行字…

linux虚拟机怎么看var文件,一种获取Linux虚拟机内部日志的方法

一种获取Linux虚拟机内部日志的方法【技术领域】[0001]本发明涉及云计算管理技术领域,特别是指一种获取Linux虚拟机内部日志的方法。【背景技术】[0002]在云计算环境下,虚拟机被广泛使用,对于虚拟机的维护要求越来越高,当虚拟机出…

详细图解mongodb 3.4.1 win7x64安装

原文:http://www.cnblogs.com/yucongblog/p/6895983.html 详细图解,记录 win7 64 安装mongo数据库的过程。安装的版本是 MongoDB-win32-x86_64-2008plus-ssl-3.4.1-signed。 我下载的源文件:mongodb-win32-x86_64-2008plus-ssl-3.4.1-signed我…

java calendar_Java Calendar complete()方法与示例

java calendarCalendar类的complete()方法 (Calendar Class complete() method) complete() method is available in java.util package. complete()方法在java.util包中可用。 complete() method is used to fills in any non-set fields in the calendar fields. complete()方…

LXD 2.0 系列(十二):调试,及给 LXD 做贡献

介绍 终于要结束了!这个大约一年前开始的这系列文章的最后一篇博文。 LXD 入门安装与配置你的第一个 LXD 容器资源控制镜像管理远程主机及容器迁移LXD 中的 DockerLXD 中的 LXD实时迁移LXD 和 JujuLXD 和 OpenStack调试,及给 LXD 做贡献如果你从一开始就…

linux用ping命令测试网速,linux下面使用命令测试网速

大家都知道在speedtest是市面上最准确最全面的测速工具,但在linux命令行不能直接使用,所以我们就借助脚本调用speedtest的接口来利用他测试网速。1.下载speedtest-cli脚本:下载地址:https://raw.githubusercontent.com/sivel/spee…

Java ArrayList isEmpty()方法与示例

ArrayList类isEmpty()方法 (ArrayList Class isEmpty() method) isEmpty() method is available in java.util package. isEmpty()方法在java.util包中可用。 isEmpty() method is used to check whether this Arraylist is "empty" or "not empty". isEmp…

linux家用系统版本,查看linux系统版本

篇一:linux下如何查看系统和内核版本linux下如何查看系统和内核版本 1. 查看内核版本命令:1) [rootq1test01 ~]# cat /proc/versionLinux version 2.6.9-22.ELsmp (bhcompilecrowe.devel.redhat.com) (gcc version 3.4.4 20050721 (Red Hat 3.4.4-2)) #1…

python中locked_Python锁类| 带示例的locked()方法

python中lockedPython Lock.locked()方法 (Python Lock.locked() Method) locked() is an inbuilt method of the Lock class of the threading module in Python. Locked()是Python中线程模块的Lock类的内置方法。 This method returns True if the lock is acquired by a th…

rocksdb ubuntu c++源码编译测试

2019独角兽企业重金招聘Python工程师标准>>> 环境: ubuntu16.4 需要安装 snappy gflage bz2 zstd 以及g 其中zstd是facebook开放源代码里的压缩的库 git clone https://github.com/facebook/rocksdb.git cd rocksdb make static_lib 成功生成 librocksd…

vs生成linux服务器程序,从Visual Studio到Linux上调试C++代码

从Visual Studio到Linux上调试C代码04/30/20155 分钟可看完本文内容[原文发表时间] 2015/4/29 10:00 PM正如您可能已经听说的那样,Visual Studio 2015新推出了对Android开发的GDB支持。有趣的是,因为这项功能依赖GDB调试,我们完全可能稍加改动…