【问题标题】:Are data races intrinsic to imperative programming and an obstacle for parallel computing?数据竞争是命令式编程固有的,还是并行计算的障碍?
【发布时间】:2016-12-08 19:35:02
【问题描述】:
说实话,我不研究这个计算领域。实际上,我的参考资料是一些网络和学术文章,然后我不安全,但对并行计算的一些概念感到好奇。
我已经制定了两个句子,并想验证它。
第一个:
命令式语言使用变量来抽象计算机的硬件内存。如果有两个并行线程并且至少有一个执行写入,而没有同步机制,则会发生数据竞争。
我们可以认为数据竞争是命令式编程范式所固有的吗?
第二个:
数据竞争会产生意想不到的结果。由于数据竞争发生在多个并行线程中,所以它们是多线程能力的问题。
我们可以认为数据竞争不仅是多线程的障碍,而且是一般并行计算的障碍?
我真正的目标是写一些与命令式编程和并行处理相关的文本来解释函数式编程的好处。欢迎任何更正和进一步的信息。
【问题讨论】:
标签:
multithreading
parallel-processing
functional-programming
race-condition
imperative-programming
【解决方案1】:
数据竞赛是关于事件年表的,甚至不是特定于代码中的语句,请考虑以下(单线程)JavaScript:
let fs = require('fs');
let dirContents = fs.readdirSync('./');
let files = dirContents.map(fname => fs.readFileSync(fname, 'utf-8'));
此代码包含数据竞争,不是因为代码本身所做的任何事情,而是因为在我们(顺序)开始读取第一个文件的时间之间,可能有其他程序出现并删除了列表中的最后一个文件以及我们尝试阅读最后一个的时间。代码看似很短,但在第 2 行和第 3 行的引擎盖下仍然存在命令式迭代。
尽管 JavaScript 是单线程的,但它充满了并发性,上述 fs 函数名称中包含“Sync”的原因是因为默认版本是异步的,并且在代码本身中引入竞争条件非常容易JavaScript。所以线程是一条红鲱鱼,它们只是使代码中存在数据竞争的可能性更大,它们的缺席证明不了任何事情。
只有两种方法可以解决此问题。一种是使用资源锁来尝试确保事件以预期的顺序发生。另一个是确保没有任何变化。这就是函数式编程方法:诸如不可变数据之类的概念,整个程序是一个大表达式而不是一系列步骤等。
*其实还有另一种方式,可以构造程序正确性的形式证明。这种方法有些不切实际,至少在计算机科学史上的这个特定时刻是这样。