这是我的理解,GHC给每个线程一个堆栈。为什么这是必要的? GHC是否编译成CPS?不是一个线程简洁地表达为闭包?为什么GHC为每个线程都有一个堆栈?
6
A
回答
5
你的问题有几个方面。
GHC运行环境中设计决策的关键参考文件是''Runtime Support for Multicore Haskell''。
回想
的GHC运行时系统支持数以百万计的轻量线程 的通过复用它们到少数的操作系统线程, 大致一个用于每个物理CPU。
和:
每个的Haskell线程运行上的无限大小的堆栈,它在 堆中分配。线程的状态及其堆栈保存在堆分配线程状态对象(TSO) 中。一个TSO的大小大约是 加上堆栈的15个字,并构成一个Haskell线程的整个状态。堆栈可以通过将TSO复制到更大的区域而增长,并且随后可以再次收缩
GHC不通过CPS进行编译。每个线程都进行递归调用,并且它们必须分配给堆栈。通过将堆栈表示为堆分配对象,事情变得更简单。
线程不仅仅是一个闭包。
当线程执行时,它开始分配给堆和堆栈。因此:
线程的堆栈,因此它的TSO是可变的。当一个 线程执行时,堆栈将累积指向新对象的指针,即 ,所以如果TSO驻留在旧代中,则必须将其添加到记录的[GC]集合的 。
堆栈指向的垃圾收集对象可以进行优化,以确保GC在与线程相同的物理线程上发生。
此外,垃圾收集器运行时, 它是高度期望的是已被一个 给定的CPU上执行的TSOS由相同的CPU上的垃圾收集器穿过, 因为TSO和数据是指可能位于该CPU的本地缓存中。
因此,GHC为每个线程都有一个堆栈,因为编译要求线程可以访问堆栈和堆。通过为每个线程提供自己的堆栈,线程可以更高效地并行执行。线程不仅仅是“封闭”,因为它们有一个可变的堆栈。
相关问题
- 1. C++堆栈/堆栈。为什么只有一个新操作员?
- 2. 为什么在linux中为每个进程保留一个内核堆栈?
- 3. 每个线程都有自己的堆栈吗?
- 4. 为什么每个应用程序都有一个JVM?
- 5. 为什么堆栈有界?
- 6. 为什么栈,堆的虚拟地址每次都改变?
- 7. 线程堆栈和进程堆栈有什么区别
- 8. 堆栈为空...为什么?
- 9. 为什么这个堆栈粉碎?
- 10. 堆栈旁边有什么线程
- 11. 每个进程有多个堆栈?
- 12. Java(JVM)如何为每个线程分配堆栈
- 13. 两个进程具有相同的堆栈指针。为什么?
- 14. 为什么每个表都必须有一个主键?
- 15. 每个进程都有自己的内核堆栈,对吧?
- 16. 为什么使用两个堆栈来创建一个队列?
- 17. 为什么堆栈和堆都需要内存分配
- 18. 打印一个进程的所有线程的线程堆栈
- 19. 每个线程或每个方法的堆栈调用?
- 20. 为什么堆栈溢出?
- 21. 为什么堆栈炸毁
- 22. 为什么。每个这里都不行?
- 23. 为什么堆栈大小有限制?
- 24. 为什么堆栈没有推动?
- 25. Xss为1个线程设置线程堆栈大小,对于所有线程的堆栈大小有什么限制
- 26. 使用堆栈ghc作为ghc的替换
- 27. 这个程序为什么产生堆栈溢出错误?
- 28. 为什么一个线程会中断另一个线程
- 29. 为什么每个JDK都带有3个JRE?
- 30. 为什么要减小Java JVM线程堆栈的大小?
您在回答“ghc管理线程如何?”方面做得很好,但问题明确提出“为什么?”。我认为这是与性能有关,但你是否愿意详细说明。 –
它始终是性能 - GHC的执行模型试图最小化线程对共享对象的争用(以利用纯度)。由于运行时需要堆栈,因此每个线程堆栈是一个明显的步骤。 –