gpt4 book ai didi

haskell - GHC 中 Haskell 线程和操作系统线程之间的关系

转载 作者:行者123 更新时间:2023-12-02 23:40:29 25 4
gpt4 key购买 nike

我试图找出 Haskell 的线程(由 forkIO 生成的线程)到底是如何映射到操作系统线程的。

我找到的第一个信息来源,

http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Concurrent.html#g:11

指定所有轻量级线程实际上都在一个操作系统线程上运行,并且只有当 Haskell 线程因安全 IO 操作而阻塞时,GHC 运行时才会生成一个新的操作系统线程来运行其他 Haskell 线程,以便 IO 调用不会'不要阻止整个程序。

第二个信息来源来自这里,

http://www.haskell.org/ghc/docs/7.0.1/html/users_guide/using-smp.html

其中明确指出,Haskell 线程以平衡的方式映射到预定义数量的预创建操作系统线程。这或多或少意味着,如果我有 80 个轻量级线程,并且在运行程序时传入了选项 +RTS -N 8,那么将创建至少 8 个操作系统线程,并且每个这样的线程将运行 10 个轻量级线程。在具有 8 个 CPU 核心的机器上,这意味着大约 10 个 Haskell 线程/核心。

第二个信息来源似乎更准确,我希望 GHC 运行时在运行使用 -threaded 标志编译的程序时表现出这种确切的行为。

有人能证实这一点吗?而且,如果第二个版本是正确的,那么绑定(bind)线程的目的是什么 - 使用 forkOS 生成的线程- 它仅用于处理使用线程本地数据的 native 代码吗?

最佳答案

没有-threaded编译的程序使用单个操作系统线程来运行所有Haskell线程。外部调用将阻止所有正在运行的 Haskell 线程。

使用-threaded编译的程序可以使用多个OS线程并行运行多个Haskell线程(OS线程的数量可以通过+RTS -N选项控制)。标记为安全的外部调用不会阻塞其他正在运行的Haskell线程(因此,即使使用+RTS -N1,使用-threaded也可能是有益的如果您有多个 Haskell 线程并发出可能需要很长时间的外部调用)。标记为不安全的外部调用在 GHC 中被实现为简单的内联函数调用,并且会阻塞调用它们的操作系统线程。

关于您的第一个来源,它从单一功能的角度描述了发出外部调用时会发生什么。一个capability定义为运行Haskell代码的虚拟CPU,在线程RTS中对应于操作系统线程的集合,任何时候只有一个线程在运行Haskell代码(其他操作系统线程用于进行外部调用而不阻塞Haskell线程) 。当 Haskell 线程进行安全外部调用时,it is put on the list of suspended threads and the capability is given to a different Haskell thread .

绑定(bind) Haskell 线程有一个固定的关联操作系统线程用于进行外部调用。 未绑定(bind)线程没有关联的操作系统线程:来自该线程的外部调用可以在任何操作系统线程中进行。绑定(bind)线程用于与库进行交互,对于库的哪些调用是从哪个操作系统线程进行的,例如 OpenGL,它将其渲染上下文存储在操作系统线程本地状态中。

更多信息可以在GHC manual中找到以及以下论文:

Extending the Haskell Foreign Function Interface with Concurrency

Simon Marlow, Simon Peyton Jones, and Wolfgang Thaller, Haskell'04

关于haskell - GHC 中 Haskell 线程和操作系统线程之间的关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12944151/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com