线程的上下文是否引用了线程的个人内存?如果是这样,多个线程之间如何共享内存?
我不是在寻找代码示例 - 我在高层次上理解同步,我只是对这个术语感到困惑,并希望对幕后实际发生的事情有所了解。
我认为/认为每个线程都有某种私有内存的原因是因为Java和.NET中的volatile关键字,以及如果不使用它们,不同的线程如何为同一个原语具有不同的值。这总是暗示了我的私人记忆。
由于我没有意识到这个术语更为通用,我想我是在询问上下文切换在Java和C#中是如何工作的。
答案 0 :(得分:35)
我认为/认为每个线程都有某种私有内存的原因是因为Java和.NET中的volatile关键字,以及如果不使用它们,不同的线程如何为同一个原语具有不同的值。这总是暗示了我的私人记忆。
好的,现在我们已经找到了您的困惑的来源。这是关于现代编程最令人困惑的部分之一。你必须围绕这个矛盾:
怎么会这样?因为
处理器出于性能原因制作内存页面的本地副本,并且只是不经常比较注释以确保所有副本都说同样的事情。如果两个线程在两个不同的处理器上,那么它们可以具有完全不一致的视图"相同的"存储器中。
单线程场景中的内存通常被认为是"仍然是"除非某些事情导致它改变。 这种直觉在多线程进程中表现不佳。如果有多个线程访问内存,则最好将所有内存视为始终处于不稳定状态,除非某些内容强制它保持静止。一旦你开始认为所有内存都在变化,就会发现两个线程的视图不一致。风暴期间没有两部海洋电影是相似的,即使是同样的风暴。
编译器可以自由地对在单线程系统上不可见的代码进行任何优化。在多线程系统上,这些优化可能突然变得可见,这可能导致数据视图不一致。
如果其中任何一个不清楚,那么首先阅读我的文章,解释什么" volatile"在C#中表示:
然后阅读" The Need For Memory Models"在万斯的文章中:
http://msdn.microsoft.com/en-us/magazine/cc163715.aspx
现在,关于线程是否有自己的内存块的具体问题,答案是肯定的,有两种方式。首先,由于线程是一个控制点,并且由于堆栈是控制流的具体化,因此每个线程都有自己的百万字节堆栈。这就是线程如此昂贵的原因。在.NET中,每次创建线程时,这些百万字节实际上都会提交到页面文件,因此请注意创建不必要的线程。
其次,线程具有恰当命名的"线程本地存储",这是与线程可用于存储有趣信息的每个线程相关联的一小部分内存。在C#中,您使用ThreadStatic
属性将字段标记为线程的本地。
答案 1 :(得分:7)
“线程上下文”的实际构成是特定于实现的,但通常我总是理解线程的上下文来引用线程的当前状态以及它在特定时间如何查看内存。这就是“上下文切换”......保存和恢复线程的状态(它的上下文)。
内存在上下文之间共享......它们是同一个过程的一部分。
我不认为自己是这个主题的专家......但这是我一直都明白的具体术语。