簡體   English   中英

IO操作是否以綠色線程運行?

[英]Do IO operations run in green threads?

給出Control.Concurrent.Async中的示例:

do a1 <- async (getURL url1)
  a2 <- async (getURL url2)
  page1 <- wait a1
  page2 <- wait a2

兩個getURL調用是在不同的OS線程上運行,還是只是在不同的綠色線程上運行?

如果我的問題沒有意義...說程序只在一個OS線程上運行,這些調用是否仍然會同時進行? 阻塞IO操作是否阻止整個操作系統線程和該操作系統線程上的所有綠色線程,或只阻止一個綠色線程?

來自Control.Concurrent.Async的文檔

此模塊提供一組操作,用於異步運行IO操作並等待其結果。 它是Control.Concurrent提供的基本並發操作的薄層。

Control.Concurrent

Haskell線程的調度在Haskell運行時系統內部完成,並且不使用任何操作系統提供的線程包。

如果不仔細解釋,這最后可能會有點誤導:盡管Haskell線程的調度 - 即選擇下一個運行的Haskell代碼 - 是在不使用任何OS工具的情況下完成的,但GHC可以並確實使用多個OS線程實際執行任何選擇運行的代碼,至少在使用線程運行時系統時。

它應該都是綠色線程。

如果您的程序是使用單線程RTS編譯(或者更確切地說是鏈接)的,那么所有綠色線程都在單個OS線程中運行。 如果您的程序是使用多線程RTS編譯(鏈接)的,則每個CPU核心調度一些任意數量的綠色線程(默認情況下)一個OS線程。

據我所知,在任何一種情況下,阻塞I / O調用應該只阻止一個綠色線程。 其他綠色線程應完全不受影響。

這並不像問題似乎暗示的那么簡單。 Haskell是一種比大多數人遇到的更強大的編程語言。 特別是, IO ,似乎從一個角度內部點塊可以被實現為順序操作的“開始非阻塞IO操作,暫停線,等待IO操作在覆蓋多個Haskell的螺紋的IO管理器來完成的,隊列IO設備准備就緒后恢復的線程。“

請參閱waitRead#waitWrite#以獲取與標准全局IO管理器一起提供該功能的api。

是否使用綠色線程與此模式無關。 可以編寫IO操作以在后台使用非阻塞IO,並使用適當的多路復用,同時顯示為其用戶提供阻塞接口。

不幸的是,它也不是那么簡單。 事實是操作系統的限制受到阻礙。 直到最近(我認為5.1內核昨天發布,也許?),Linux沒有為非阻塞磁盤操作提供良好的接口。 當然有些事情看起來應該有效,但在實踐中它們並不是很好。 因此,磁盤讀/寫是GHC中的實際阻塞操作。 (不僅僅是在Linux上.GHC沒有很多開發人員支持它,所以很多東西都是用在linux上運行的相同代碼編寫的,即使還有其他選擇。)

但它甚至不像“網絡操作隱藏無阻塞,磁盤操作阻塞”那么簡單。 至少可能不是。 我實際上並不知道,因為在非線程運行時上找到文檔很難。 我知道線程運行時實際上維護了一個單獨的線程池,用於執行標記為“安全”的FFI調用,這可以防止它們阻止執行綠色線程。 我不知道非線程運行時是否也是如此。

但是對於你的例子,我可以說 - 假設getURL使用標准網絡庫(無論如何它是一個假設的函數),它將在后台進行適當的多路復用的非阻塞IO。 因此,即使沒有線程運行時,這些操作也將是真正的並發。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM