并发冲突控制与数据共享[原文发表时间:2005年3月19日]
2006-08-03 14:55
351 查看
原文出处:http://pluralsight.com/blogs/hsutter/archive/2005/03/19/6804.aspx
Iain McInnes(译者注:多优先权管理(MPM,Multiple Priority Management)领域专家)曾在一则评论中说,他找到了并发冲突的解决办法:
不要在线程之间共享数据,真的。当然,和当年的人习惯于使用GOTO一样,必须有替代办法才行。我认为就是异步消息交换。
完全赞同!这就是问题的关键,去年晚些时候,我就是在此思想的指导下展开一项设计活动的。数据共享的确给我们带来了很多麻烦,包括并发冲突,以及其他很多方面(如古老而无法割舍的单线程交换模式)。异步通讯乃解决之道。
认识到这一点,仅仅是万里长征走完了第一步。接下来要走哪几步,虽然还算清楚(比如为语言增加future特性[译注1]),但为保证语言的高易用性所需的设计工作量是非常巨大的。比如:
1、编程语言(特别是命令式语言,Imperiative Language),如何最大程度帮助开发者发现应用里潜在的并发冲突(在函数式语言(Functional Language)中,并发冲突已经得到很好解决[译注2])?
2、粗粒度(如任务级,task-level)和细粒度(如循环级,loop-level)的并发冲突如何分别处理,同种语言可以在各粒度层次上处理好并发问题么?
3、如何满足某些时候,不同线程必须交互信息的要求呢,通过某种协议的交换数据么?
单独去看每个问题,我们都已经有了解决办法,现在要做的工作是将这些解决方案集成到主流的程序设计语言中,并要求语言有较好的易用性。这就是我说的面向对象并发控制(OO of concurrency)——这和在语言中引入类和虚函数的扩展过程是类似的。
Ada95和Java在这方面已经取得了一定进展;同样,一些研究性语言,比如µC++,还有OpenMP(我觉得它很象工厂里用的传送带,虽然结实,但实在丑陋)也是如此——但无一例外地,它们都只是做了一些改进工作而已,基本的东西并没有变化,特别是仍然依赖于数据共享和资源锁定。另外一些研究型语言(如Polyphonic C# (Comega))走得更远一些——它们做了有趣的探索,但关键问题是,这些语言偏向于Lisp和Prolog之类的思维模式,现在的主流程序员难以适应,要想让他们在思维方式做这么大的转变,显然是不现实的。长期以来,函数式语言展示了自己在并发环境很好的适应性,但我对主流程序员将函数式语言作为主要商业应用语言持怀疑态度,毕竟,它和命令式语言使用模式相差太大了。
所以说,虽然人们已经做了大量有价值的研究,在很多个体问题上都找到了有效的解决办法,而我们现在需要将这些办法平滑、干练,并在保持良好适应性的前提下融入到目前广泛使用的命令式编程语言。很多人,包括我,正在朝这个方向努力。
译注1
一种同步实现模式。某线程在future上等待(比如等待获得一个值,等着拥有它),这时候线程被临时阻塞,处于悬挂状态;其他对此future具有控制权的线程可以释放future,从而失去控制权,先前等待future的线程悬挂状态解除,获得future的控制,继续执行。
比如Java中Object.wait/notify/notifyall体现的就是这种实现模式。
译注2
狭义来说,函数式语言定义一系列高度抽象的函数,执行时不涉及对具体数据的操作,不依赖于诺伊曼体系结构。因此不会带来并发冲突问题,没有“副作用”(side effects)。例如:LISP、FP和ML。
有关计算机语言的分类和发展历史,大家可以到网上搜索资料。这里就有一篇,可供参考:《程序设计语言的发展》(郑州轻工业学院学报)。
Iain McInnes(译者注:多优先权管理(MPM,Multiple Priority Management)领域专家)曾在一则评论中说,他找到了并发冲突的解决办法:
不要在线程之间共享数据,真的。当然,和当年的人习惯于使用GOTO一样,必须有替代办法才行。我认为就是异步消息交换。
完全赞同!这就是问题的关键,去年晚些时候,我就是在此思想的指导下展开一项设计活动的。数据共享的确给我们带来了很多麻烦,包括并发冲突,以及其他很多方面(如古老而无法割舍的单线程交换模式)。异步通讯乃解决之道。
认识到这一点,仅仅是万里长征走完了第一步。接下来要走哪几步,虽然还算清楚(比如为语言增加future特性[译注1]),但为保证语言的高易用性所需的设计工作量是非常巨大的。比如:
1、编程语言(特别是命令式语言,Imperiative Language),如何最大程度帮助开发者发现应用里潜在的并发冲突(在函数式语言(Functional Language)中,并发冲突已经得到很好解决[译注2])?
2、粗粒度(如任务级,task-level)和细粒度(如循环级,loop-level)的并发冲突如何分别处理,同种语言可以在各粒度层次上处理好并发问题么?
3、如何满足某些时候,不同线程必须交互信息的要求呢,通过某种协议的交换数据么?
单独去看每个问题,我们都已经有了解决办法,现在要做的工作是将这些解决方案集成到主流的程序设计语言中,并要求语言有较好的易用性。这就是我说的面向对象并发控制(OO of concurrency)——这和在语言中引入类和虚函数的扩展过程是类似的。
Ada95和Java在这方面已经取得了一定进展;同样,一些研究性语言,比如µC++,还有OpenMP(我觉得它很象工厂里用的传送带,虽然结实,但实在丑陋)也是如此——但无一例外地,它们都只是做了一些改进工作而已,基本的东西并没有变化,特别是仍然依赖于数据共享和资源锁定。另外一些研究型语言(如Polyphonic C# (Comega))走得更远一些——它们做了有趣的探索,但关键问题是,这些语言偏向于Lisp和Prolog之类的思维模式,现在的主流程序员难以适应,要想让他们在思维方式做这么大的转变,显然是不现实的。长期以来,函数式语言展示了自己在并发环境很好的适应性,但我对主流程序员将函数式语言作为主要商业应用语言持怀疑态度,毕竟,它和命令式语言使用模式相差太大了。
所以说,虽然人们已经做了大量有价值的研究,在很多个体问题上都找到了有效的解决办法,而我们现在需要将这些办法平滑、干练,并在保持良好适应性的前提下融入到目前广泛使用的命令式编程语言。很多人,包括我,正在朝这个方向努力。
译注1
一种同步实现模式。某线程在future上等待(比如等待获得一个值,等着拥有它),这时候线程被临时阻塞,处于悬挂状态;其他对此future具有控制权的线程可以释放future,从而失去控制权,先前等待future的线程悬挂状态解除,获得future的控制,继续执行。
比如Java中Object.wait/notify/notifyall体现的就是这种实现模式。
译注2
狭义来说,函数式语言定义一系列高度抽象的函数,执行时不涉及对具体数据的操作,不依赖于诺伊曼体系结构。因此不会带来并发冲突问题,没有“副作用”(side effects)。例如:LISP、FP和ML。
有关计算机语言的分类和发展历史,大家可以到网上搜索资料。这里就有一篇,可供参考:《程序设计语言的发展》(郑州轻工业学院学报)。
相关文章推荐
- 并发冲突控制与数据共享[原文发表时间:2005年3月19日]
- 并发冲突控制与数据共享[原文发表时间:2005年3月19日]
- 并发冲突控制与数据共享[原文发表时间:2005年3月19日]
- 做项目时,如何进行数据并发冲突的控制
- 【C++11 并发编程教程 - Part 2 : 保护共享数据(bill译)】
- 庭审管理中动态显示今天起7日内的数据,动态查询,并根据已有数据判断新增和修改时的时间冲突问题
- 并发-同步访问共享的可变数据
- 线程并发 共享数据及线程并发
- 多线程和并发库应用七-线程间数据共享2
- java多线程与线程并发五:多个线程访问共享对象和数据的方式
- C++并发编程2——为共享数据加锁(四)
- 在Linq to Sql中管理并发更新时的冲突(3):使用记录的时间戳进行检测
- 在Linq to Sql中管理并发更新时的冲突(3):使用记录的时间戳进行检测 推荐
- Java并发05---线程范围内的共享数据
- 2006年4月度国际标准化组织C++会议纪要[原文发表时间:2006年5月3日]
- Java高并发编程:多个线程之间共享数据的方式探讨
- Qt QHash 和QMap 区别时间: 2010-11-17 / 浏览次数: 75 views / 1个评论 发表评论QMap提供了一个从类项为key的键到类项为T的直的映射,通常所存储的数据类型是一个键对应一个直,并且按照Key的次序存储数据,
- 垃圾收集特性与类型系统[原文发表时间:2004年10月14日]
- 多线程并发库高级应用 之 多个线程之间共享数据的方式探讨
- 用乐观并发方式处理数据库并发冲突以保证数据一直性的代码处理方法