了解线程化 GHC haskell 程序的子进程
Understanding the child process of a threaded GHC haskell program
我试图了解父线程和各种子 OS 线程如何在使用 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)
随着我的变化 +RTS -N
.
,我似乎得到了 N*2 + 1
个 "hello:w" 线程
这些 "hello:w" 线程是什么,为什么每个 HEC + 1 显然有两个线程?
ghc_ticker
是做什么的?
我还注意到我正在使用 +RTS -N4
测试的大型真实服务,例如这些 "my-service:w" 线程中的 14 个,在负载下这些进程 ID 似乎在搅动(其中一半在我终止服务之前保持活动状态)。
为什么是 14 个,为什么有一半生成并死亡?
我也会接受一个答案,该答案有助于指导我使用我的代码来解决后两个问题。
spawned at startup, it runs this function中的ghc_ticker
。它的目的被描述为
The interval timer is used for profiling and for context switching in
the threaded build.
其他 *:w
个线程是工作线程,它们是 created whenever there is more work to do (aka Task), but there are no more spare workers, see here
在启动时,ghc 为每个功能创建一个 worker,然后根据需要创建它们并在可能的情况下重复使用。很难说为什么 -N4
案例中有 14 个工人。我只能猜测它们正在为 IO 管理器线程提供服务:参见 here。我们也不要忘记 FFI——FFI 调用可能会阻塞 worker。你可以试试在createOSThread
下个断点看看为什么要创建worker
您可以阅读有关调度程序的更多信息here
添加:
嗯,我想我可以解释一下 N*2+1
工人:N
每个能力的工人是在启动时创建的; N
更多 - IO 管理器事件循环,每个功能一个;加上一个 IO 管理器计时器线程。虽然我不确定为什么第一个 N
worker(在启动时创建)没有被 IO 管理器线程重用。
我试图了解父线程和各种子 OS 线程如何在使用 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)
随着我的变化 +RTS -N
.
N*2 + 1
个 "hello:w" 线程
这些 "hello:w" 线程是什么,为什么每个 HEC + 1 显然有两个线程?
ghc_ticker
是做什么的?
我还注意到我正在使用 +RTS -N4
测试的大型真实服务,例如这些 "my-service:w" 线程中的 14 个,在负载下这些进程 ID 似乎在搅动(其中一半在我终止服务之前保持活动状态)。
为什么是 14 个,为什么有一半生成并死亡?
我也会接受一个答案,该答案有助于指导我使用我的代码来解决后两个问题。
spawned at startup, it runs this function中的ghc_ticker
。它的目的被描述为
The interval timer is used for profiling and for context switching in the threaded build.
其他 *:w
个线程是工作线程,它们是 created whenever there is more work to do (aka Task), but there are no more spare workers, see here
在启动时,ghc 为每个功能创建一个 worker,然后根据需要创建它们并在可能的情况下重复使用。很难说为什么 -N4
案例中有 14 个工人。我只能猜测它们正在为 IO 管理器线程提供服务:参见 here。我们也不要忘记 FFI——FFI 调用可能会阻塞 worker。你可以试试在createOSThread
下个断点看看为什么要创建worker
您可以阅读有关调度程序的更多信息here
添加:
嗯,我想我可以解释一下 N*2+1
工人:N
每个能力的工人是在启动时创建的; N
更多 - IO 管理器事件循环,每个功能一个;加上一个 IO 管理器计时器线程。虽然我不确定为什么第一个 N
worker(在启动时创建)没有被 IO 管理器线程重用。