当你想在Haskell中使用多个核心时,我试着理解真正发生了什么。 This给出了一个很好的介绍,但恕我直言并不是很关键,并留下许多问题。
当我在我的代码中使用par combinator或forkIO并使用-threaded标志编译它时,最终决定我是否获得OS线程?是编译器还是操作系统?
如果我使用应该始终创建操作系统线程的forkOS,那是否会让我摆脱底层操作系统的功能?
澄清我的问题:我认为在多核世界中,底层/已安装的操作系统在其可以理解和使用的核心数量方面存在局限性。我在Haskell中所做的一切是否被操作系统的功能所截断?或者,有没有什么方法(它们是什么?)在某种意义上比OS更好,如果一个主机有12个内核而OS主控8,我可以通过在Haskell中编写智能应用程序来推动它,或者我在这台操作系统上运行的所有东西都限于智能使用8核?
答案 0 :(得分:10)
Haskell运行时决定要创建多少OS线程。操作系统决定如何将这些线程映射到物理核心和处理器。编译器实际上与它无关,我认为......
这里有一些层次。 (请注意,编译器不在此图中。)
+-----------------+ | User code | +-----------------+ | | forkIO creates v +-----------------+ | Haskell threads | +-----------------+ | | Runtime library maps to v +-----------------+ | OS Threads | +-----------------+ | | OS scheduler runs on v +-----------------+ | Physical cores | +-----------------+
操作系统永远不会为您创建操作系统线程,这不是它的工作。操作系统仅执行应用程序和运行时库指示它执行的操作。操作系统只能为物理内核上的现有操作系统线程安排运行时。
运行时库选择创建多少OS线程以及代码的哪些部分在哪个线程上运行。您可以控制它,但它的一个功能是将您的代码映射到OS线程。
如您所见,如果操作系统仅限于使用8个内核,则无法使用12.您无法绕过操作系统限制。但是,现代操作系统支持的内核比您拥有的多,所以不用担心。 (如果您使用的是Windows XP,则需要使用2个内核。但在具有2个以上内核的计算机上运行Windows XP是愚蠢的。)
答案 1 :(得分:2)
在运行程序时,要获得四个OS线程,您可以在命令行中使用+ RTS -N4 -RTS选项。要获得不同于4的数字,您只需替换它。默认情况下(非线程运行时)你只能获得一个OS线程,尽管你可以在其中运行很多GHC的轻量级IO线程。对于-N4,运行时在程序启动时启动4个总线程,然后将IO线程传递给它们。
是的,您可以使用forkOS显式启动OS线程。您可能想要这样做的原因是,如果您通过FFI调用C函数,可能会使用阻塞I / O,并且如果它在相同的OS线程中运行,则会冻结其他轻量级线程。否则让运行时处理OS线程。
您应该从这里开始阅读与Haskell并发相关的文章: