我对它的第一印象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 的值以及不再引用的文件描述符?还是有一些单独的机制来管理文件描述符资源?无论机制是什么,它似乎都运行得很好——你怎么知道什么时候最好hClose
显式使用?