最近,我讨论了为什么seq in Java Actors demo
上存在易变标记@volatile private var seq = 0L
private def nextSeq: Long = {
val next = seq
seq += 1
next
}
一个答案是线程可以迁移并且变量丢失(其他核心在其私有缓存中将具有不连贯的值)。但是,您通常不会使用volatile
标记每个变量以启用多核执行。因此,无论何时切换上下文,核心都必须刷新缓存。但是,我无法在任何地方发现此声明。每个人,例如。维基百科,只关心寄存器和堆栈内存
进程的状态包括进程的所有寄存器 可能正在使用,尤其是程序计数器,以及任何其他操作 可能需要的系统特定数据。这个数据通常是 存储在称为过程控制块(PCB)的数据结构中,或 switchframe。为了切换过程,首先是PCB 必须创建并保存过程。 PCB有时存储在其上 内核内存中的每进程堆栈(与用户模式调用相反) 堆栈),或者可能存在一些特定的操作系统定义的数据 这个信息的结构。
我们在迁移通用数据/变量方面有什么实际意义?
答案 0 :(得分:4)
每当有任何类型的上下文切换时,操作系统将保存其状态,以便可以在任何内核上重新启动它(假设它没有使用处理器关联功能绑定到特定内核)。
保存由于某种原因或其他原因不完整的状态会破坏线程或处理的整个目的,因此缓存会作为切换的一部分被刷新。
Volatile与上下文切换没有任何关系。它只是告诉编译器内存位置如有变更,恕不另行通知,因此每次源代码指示时都必须访问它,即优化对内存位置访问的通常编译器行为不适用于volatile声明的位置。