jbe*_*man 6 multithreading haskell ghc child-process
我试图了解父级和各种子OS线程如何在使用GHC编译的haskell程序中工作-threaded。
使用
module Main where
import Control.Concurrent
main = do
threadDelay 9999999999
Run Code Online (Sandbox Code Playgroud)
我可以-threaded在ghc 8.6.5上编译并运行,+RTS -N3例如
$ pstree -p 6615
hello(6615)???{ghc_ticker}(6618)
??{hello:w}(6616)
??{hello:w}(6617)
??{hello:w}(6619)
??{hello:w}(6620)
??{hello:w}(6621)
??{hello:w}(6622)
??{hello:w}(6623)
Run Code Online (Sandbox Code Playgroud)
看起来N*2 + 1随着我的变化,我得到了这些“ hello:w”线程+RTS -N。
这些“ hello:w”线程是什么,为什么每个HEC + 1显然有两个线程?
怎么ghc_ticker办?
我还注意到,在我正在测试的大型真实服务中+RTS -N4,例如,我获得了14个“ my-service:w”线程,在负载下,这些进程ID似乎搅动(其中一半保持活动状态,直到我杀死了服务)。
为什么14,为什么其中一半会生成并死亡?
我还将接受一个答案,该答案有助于指导我检测代码以找出后两个问题。
在启动时生成ghc_ticker,它运行此函数。其目的描述为
间隔计时器用于分析和线程构建中的上下文切换。
其他*:w线程是工作线程,每当有更多工作要做(又名任务)时就会创建它们,但没有更多的空闲工作线程,请参见此处
启动时,ghc 为每个功能创建一个工作人员,然后根据需要创建它们并在可能的情况下重用。很难说为什么你有 14 名工人以防-N4万一。我只能猜测它们正在为 IO 管理器线程提供服务:请参阅此处。我们也不要忘记 FFI - FFI 调用可能会阻塞工作人员。您可以尝试放置一个断点createOSThread来查看为什么创建worker。
添加:嗯,我想我可以解释N*2+1工人:N每个能力的工人是在启动时创建的;Nmore - IO 管理器事件循环,每种功能一个;加上一个 IO 管理器定时器线程。虽然我不确定为什么第一个N工作线程(在启动时创建)没有被 IO 管理器线程重用。