Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 为什么不能只使用满足互斥和死锁自由的“1”共享变量来实现“2”线程的锁?_Multithreading - Fatal编程技术网

Multithreading 为什么不能只使用满足互斥和死锁自由的“1”共享变量来实现“2”线程的锁?

Multithreading 为什么不能只使用满足互斥和死锁自由的“1”共享变量来实现“2”线程的锁?,multithreading,Multithreading,我一直在实践层面上大量研究并发性,因此我也开始从理论上研究并发性,以深入了解计算机科学的这一领域 但是,我很难理解以下内容: 为什么不能仅使用满足互斥和死锁自由的1共享变量来实现2-线程的锁 更一般地说,为什么n线程锁至少需要n共享变量来满足互斥和死锁自由 考虑两个线程A和B。我看到A必须写入这个变量,以表示它获得了锁。变量可以是布尔值。是因为A在写入变量之前需要读取变量,这是两个操作吗?(不是原子化的)最有可能的情况是,您阅读的内容对平台的功能做出了不再现实的假设。您可能正在考虑这样一种情况:

我一直在实践层面上大量研究并发性,因此我也开始从理论上研究并发性,以深入了解计算机科学的这一领域

但是,我很难理解以下内容:

为什么不能仅使用满足互斥和死锁自由的
1
共享变量来实现
2
-线程的锁

更一般地说,为什么
n
线程锁至少需要
n
共享变量来满足互斥和死锁自由


考虑两个线程
A
B
。我看到
A
必须写入这个变量,以表示它获得了锁。变量可以是布尔值。是因为
A
在写入变量之前需要读取变量,这是两个操作吗?(不是原子化的)

最有可能的情况是,您阅读的内容对平台的功能做出了不再现实的假设。您可能正在考虑这样一种情况:CPU没有预取、没有发布写入、总读取和存储顺序、没有影响内存可见性或内存操作顺序的编译器优化、没有单词撕裂风险,但没有像增量或比较交换这样的原子“读-修改-写”操作。有了这些假设,真的没有办法用一个变量来实现

这是一个有趣的理论问题,但几乎没有实际意义。现代CPU确实具有所有这些优化功能——它们预取读取、向缓冲区发布写入、重新排列读取和存储顺序,以及编译器优化内存选项。对于与本机整数类型对齐的操作,字撕裂通常不是问题。但是,更重要的是,现代CPU具有复杂、高性能的原子操作,如递增、递减、比较交换等

当您编写同步原语时,练习是高度特定于平台的。可供您使用的功能组合因平台而异。更重要的是,它们的成本因平台而异,因此即使有许多解决方案,它们也可能不一样好

最后,您必须深入了解每个原语实际上使平台做了什么。例如,在现代Intel CPU上,存在超线程。例如,一个等待自旋锁的线程不会使另一个共享物理内核的线程饥饿,这一点很重要。这需要深入了解超线程的实际工作原理。类似地,编写自旋锁也很容易,这样,当您获得锁时,您就可以获得所有预测失误的分支,并在性能最为关键的时刻中断管道。您需要了解分支预测是如何工作的,以及它如何与指令管道交互以避免此问题


绝大多数程序员永远不应该编写同步原语并在实际的、真实的代码中使用它们。让他们以有保证的可靠性工作是很困难的,让他们正常工作是非常困难的。最重要的是,不可能轻易衡量他们的表现。(当然,进行实验是很好的,只要你对实验代码的有用性没有过分的感觉。)

这肯定是因为一些关于你可以执行什么操作和不能执行什么操作的假设,而你还没有告诉我们你的假设是什么。你可能假设你有完美的内存可视性和顺序,但没有原子的读-修改-写操作。读,写和这些简单的指令都是原子的。对,但是读-修改-写操作(如增量或测试和设置)又如何呢?读/写锁通常由一个存储写入和读取计数的变量实现。。。基本上是两把锁。因此,不可能这样做的假设是错误的。@Voo当然,但该计数是通过原子读修改写操作访问的。我相信OP假设了完美的内存可视性和完美的顺序,但没有读-修改-写操作。