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
?
我相信這只是導致文件描述符關閉的GC。 –
一般來說,最好使用確保確定性資源(除內存之外)處理的機制,這在Haskell中應該是'bracket'。除了一個簡單的例子,不要相信GC和文件。 –
括號只對嚴格IO有意義 - 否則效果可能會通過惰性數據泄漏出去。 –