與其試圖直接回答您的問題,我會嘗試爲多線程Haskell程序的實現提供一個概念模型。我會忽略許多細節和複雜性。
操作系統執行preemptive multithreading使用hardware interrupts允許計算的多個「線程」在邏輯上同時運行在同一個內核上。
操作系統提供的線程往往是重量級的。它們非常適合某些類型的「多線程」應用程序,並且在像Linux這樣的系統上,它們基本上是同一個工具,允許多個程序同時運行(他們擅長的任務)。
但是,這些線程對於Haskell等高級語言的許多用途來說有點重量。從本質上講,GHC運行時作爲小型操作系統,在操作系統線程之上實現自己的「線程」,就像操作系統在內核之上實現線程一樣。
從概念上很容易想象像Haskell這樣的語言將以這種方式實現。評估Haskell包含「強制thunk」,其中thunk是一個計算單位,可能依賴於另一個值(thunk)和/或2.創建新thunk。
因此,可以想象多個線程同時評估thunk。人們會構建一個被評估的thunk隊列。每個線程將彈出隊列的頂部,並評估該thunk直到完成,然後從隊列中選擇一個新的thunk。操作par
及其同類可以通過向該隊列添加一個thunk來「激發」新的計算。
將此模型擴展到IO操作並不是特別難以想象。我們認爲Haskell計算的單位稍微複雜一些,而不是簡單地強制純粹的thunk。僞哈斯克爾這種運行時:
type Spark = (ThreadId,Action)
data Action = Compute Thunk | Perform IOAction
注意:這僅僅是爲了概念上的理解,不要以爲事情以這種方式實現
當我們運行一個火花,我們期待爲例外「扔」到該線程ID。假設我們沒有,執行包括強制執行thunk或執行IO操作。
顯然,我在這裏的解釋一直很手動,並且忽略了一些複雜性。有關更多信息,GHC團隊撰寫了優秀的文章,例如Marlow等人的「多核Haskell運行時支持」。您可能還想看看操作系統上的教科書,因爲他們經常深入瞭解如何構建調度程序。
您可能有興趣閱讀http://community.haskell.org/~simonmar/papers/conc-ffi.pdf,它很好地解釋了多線程Haskell的實現。這有點舊,但仍然非常重要。儘管有這個頭銜,但它遠遠超過FFI。 –