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有意义 - 否则效果可能会通过惰性数据泄漏出去。 –