作为多线程和互斥体的新手,我正在浏览维基百科.我遇到了这个部分:
通过创建链接列表,CAS可用于实现任何共享数据结构的无等待互斥,其中每个节点表示要执行的所需操作.然后,在插入新节点期间,CAS用于更改链表中的指针.只有一个过程可以在CAS中成功; 尝试同时添加节点的所有其他进程将不得不再次尝试.然后,每个进程可以保留数据结构的本地副本,并且在遍历链接列表时,可以从其本地副本上的列表执行每个操作.
现在我理解CAS的基本概念,其中我们基本上使用原子操作将值与预定值进行比较,如果匹配则我们交换它们.但我无法遵循"所需操作链表"的含义?为什么所有流程都遵循相同的链接操作列表?
轻型事务的Datastax文档指出:
“轻量级事务使用的时间戳机制与正常操作不同,并且混合LWT和正常操作会导致错误。如果轻量级事务用于在分区内的行中写入,则应仅对读写操作使用轻量级事务。 ”
这非常模糊(顺便说一句,对于读操作,LWT甚至意味着什么?)。
混合LWT和普通写入时,对Cassandra内部知识有更深入了解的人可以详细说明可能出现的问题吗?
我最好的猜测是并发性可能存在问题(显然)。但是我以为,如果我(例如)使用插入了一行,IF NOT EXISTS并且如果成功的话,我以后再UPDATE对同一分区进行处理,那会很好。我错了吗?
The question is about the latest iOS and macOS. Suppose I have the following implementation for an atomic Int64 in Swift:
struct AtomicInt64 {
private var _value: Int64 = 0
init(_ value: Int64) {
set(value)
}
mutating func set(_ newValue: Int64) {
while !OSAtomicCompareAndSwap64Barrier(_value, newValue, &_value) { }
}
mutating func setIf(expectedValue: Int64, _ newValue: Int64) -> Bool {
return OSAtomicCompareAndSwap64Barrier(expectedValue, newValue, &_value)
}
var value: Int64 { _value }
}
Run Code Online (Sandbox Code Playgroud)
Note the value accessor: is it safe?
If not, …
在阅读并发编程时,我在比较和交换以及比较和设置操作中遇到了共识数这个术语.我无法理解这个术语的含义,任何人都可以解释一下吗?
谢谢!!
concurrency multithreading concurrent-programming compare-and-swap
InterlockedCompareExchange在 Windows 中,以及__sync_val_compare_and_swap在 gcc 中,都采用指针,因此我可以将任何地址(例如指向共享内存块的地址)传递到这些函数中。
对于非 x86 架构,我可能必须确保内存对齐以确保正确性,而对于 x86(也许还有其他架构),我可能希望确保缓存行对齐以提高性能,尽管正确性不应该成为问题(-> x86 前缀LOCK) 。
为了摆脱我的代码中一些依赖于平台的东西(Windows VC++ 与 GCC),我查看了 C++11atomic_compare_exchange_weak和朋友。但它们都作用于类型的变量std::atomic<T>*。
有没有办法在 C++11 的原子函数中使用任意指针?看起来简单的std::atomic 转换并不能解决这个问题。
我正在阅读英特尔开发人员手册的第 3a 卷:
在第 245 页,它暗示只有XCHG指令具有自动总线锁定功能。诸如XADD和 之类的指令CMPXCHG不会自动锁定系统总线,为此您需要以LOCK.为前缀。对我来说,这表明单独的指令不是跨多个 CPU 内核的原子。
那么这些指令的目的是什么,如果它们不是原子的呢?
在我阅读手册之前,我预计这些指令在 CPU 级别本质上是原子的。我认为这就是结合“比较”和“设置”功能的原因。
编辑:
原因可能是在单个 CPU 内核上强制执行原子性??
Java通过其原子类公开CAS操作,例如
boolean compareAndSet(expected,update)
Run Code Online (Sandbox Code Playgroud)
JavaDocs指定了compareAndSet 操作的内存效应,如下所示:
CompareAndSet 和所有其他读取和更新操作(例如 getAndIncrement)都具有读取和写入 易失性变量的记忆效应。
这绝对适用于成功的compareAndSet调用。但是如果compareAndSet返回,记忆效应也成立吗false?
我想说,不成功compareAndSet对应于易失性读取(因为在这种情况下必须访问原子实例的当前值),但我不明白为什么 CAS 应该在不成功的情况下执行特殊的内存屏障指令。
问题实际上是,不成功的 CAS 是否也建立了happens-before关系。考虑以下程序:
public class Atomics {
private static AtomicInteger ai = new AtomicInteger(5);
private static int x = 0;
public static void main(String[] args) {
new Thread(() -> {
while (x == 0) {
ai.compareAndSet(0, 0); // returns false
}
}, "T1").start();
new Thread(() -> {
x = 1;
ai.compareAndSet(0, 0); // returns false
}, "T2").start();
}
}
Run Code Online (Sandbox Code Playgroud)
线程T2(和程序)肯定会终止吗?
Java 的AtomicInteger优惠public final boolean compareAndSet(int expect, int update)。如果false返回,我想知道比较失败时的实际值是多少。这在Java中可能吗?
在 .Net 中,有public static int CompareExchange(ref int location1, int value, int comparand), 总是返回原始值。
我不小心从Kamon Monitoring工具中遇到了Striped64.java类.在第95行,我发现了这个评论:
JVM intrinsics note: It would be possible to use a release-only
form of CAS here, if it were provided.
Run Code Online (Sandbox Code Playgroud)
虽然我理解CAS是什么,但我无法找出CAS的唯一形式.有人可以对此有所了解吗?
我正在查看来自 OpenJDK12 的 JVM HotSpot 中的自旋锁实现。这是它的实现方式(保留评论):
// Polite TATAS spinlock with exponential backoff - bounded spin.
// Ideally we'd use processor cycles, time or vtime to control
// the loop, but we currently use iterations.
// All the constants within were derived empirically but work over
// over the spectrum of J2SE reference platforms.
// On Niagara-class systems the back-off is unnecessary but
// is relatively harmless. (At worst it'll slightly retard
// acquisition times). The back-off is critical for …Run Code Online (Sandbox Code Playgroud)