【问题标题】:Understanding the child process of a threaded GHC haskell program了解线程化 GHC haskell 程序的子进程
【发布时间】:2019-11-26 18:58:48
【问题描述】:

我试图了解父操作系统线程和各种子操作系统线程如何在使用 GHC -threaded 编译的 haskell 程序中工作。

使用

module Main where
import Control.Concurrent
main = do
    threadDelay 9999999999

例如在 ghc 8.6.5 上使用 -threaded 编译,并使用 +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)

看起来我得到了N*2 + 1 这些“hello:w”线程,因为我改变了+RTS -N

这些“hello:w”线程是什么,为什么每个 HEC + 1 显然有两个?

ghc_ticker 是做什么的?

我还注意到我正在使用 +RTS -N4 测试的大型真实服务,例如这些“my-service:w”线程中的 14 个,并且在负载下这些进程 ID 似乎在搅动(其中一半在我终止服务之前保持活动状态)。

为什么是 14 个,为什么有一半会生成并死亡?

我也接受一个有助于指导我检测我的代码以找出后两个问题的答案。

【问题讨论】:

  • 很确定这些是safe ffi 调用的线程池。

标签: multithreading haskell ghc child-process


【解决方案1】:

spawned 中的ghc_ticker 在启动时运行this function。它的目的被描述为

间隔计时器用于分析和上下文切换 线程构建。

其他 *:w 线程是工作线程,只要有更多工作要做(又名Task),它们就是created,但没有更多空闲工作线程,请参阅here

在启动时,ghc 会为每个功能创建一个工作器,然后根据需要创建它们并在可能的情况下重用它们。很难说为什么在-N4 案例中有 14 名工人。我只能猜测他们正在为 IO 管理器线程提供服务:请参阅 here。我们也不要忘记 FFI - FFI 调用可能会阻止工作人员。您可以尝试在createOSThread 中放置一个断点,以查看创建worker 的原因。

您可以阅读有关调度程序的更多信息here

添加: 嗯,我想我可以解释一下 N*2+1 工人:N 每个能力的工人是在启动时创建的; N 更多 - IO 管理器事件循环,每个功能一个;加上一个 IO 管理器计时器线程。虽然我不确定为什么第一个 N 工作人员(在启动时创建)没有被 IO 管理器线程重用。

【讨论】:

    猜你喜欢
    • 2011-10-12
    • 2016-01-13
    • 2011-10-17
    • 2012-11-03
    • 2013-11-26
    • 1970-01-01
    • 2011-09-22
    • 2013-01-10
    • 2011-09-01
    相关资源
    最近更新 更多