2012-05-29 74 views
8

readFile我對readFile的第一印象是在它的方便性和它將文件描述符打開時間長於需要的可能性之間進行權衡,無法關閉它們。作爲一個實驗我嘗試以下(非常實用)計劃,認爲它可能是由試圖維持一千打開的文件描述符嗆:什麼時候明確關閉文件句柄?

main = do 
    mapM_ (\idx -> readIt) [1..1000] 
    where readIt = do 
      contents <- readFile "/etc/passwd" 
      putChar $ head contents 

但它實際上回收文件描述符的一個不錯的工作;計數從未超過70左右:

open("/etc/passwd", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = 4 
open("/etc/passwd", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = 5 
open("/etc/passwd", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = 6 
open("/etc/passwd", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = 7 
... 
open("/etc/passwd", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = 65 
open("/etc/passwd", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = 66 
close(3)        = 0 
close(4)        = 0 
close(5)        = 0 
... 
close(54)        = 0 
close(55)        = 0 
close(56)        = 0 
open("/etc/passwd", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = 3 
open("/etc/passwd", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = 4 

這是怎麼發生的?難道只是contents的值正在GC'd,並且它們沒有被引用的文件描述符?還是有一些獨立的管理文件描述符資源的機制?不管是什麼機制,它似乎都工作得很好 - 你怎麼知道什麼時候最好明確地使用hClose

+1

我相信這只是導致文件描述符關閉的GC。 –

+0

一般來說,最好使用確保確定性資源(除內存之外)處理的機制,這在Haskell中應該是'bracket'。除了一個簡單的例子,不要相信GC和文件。 –

+1

括號只對嚴格IO有意義 - 否則效果可能會通過惰性數據泄漏出去。 –

回答

8

只有當您有一些您可以實際手動執行的低級別資源約束時,才能自行顯式關閉資源。

的情況來考慮:通過懶惰IO獲得性

  • 資源:必須使用GC來釋放資源
  • 嚴格IO:一次讀取輸入可以手動關閉;或使用包圍組合器(例如finallybracket
  • 增量IO(管道,迭代):讓框架爲你關閉它。
7

Haddock docs for System.IO有這樣一段話:

GHC注:把手會在垃圾收集器檢測到它已成爲程序未引用自動關閉。但是,通常不推薦依賴這種行爲:垃圾收集器是不可預測的。如果可能,使用明確的hClose關閉句柄,當它們不再需要時。 GHC當前沒有嘗試釋放文件描述符,因此您有責任確保這種情況不會發生。

相關問題