Моим первым впечатлением от 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
подвергаются сборке мусора, а вместе с ними и файловые дескрипторы, на которые больше нет ссылок? Или есть какой-то отдельный механизм для управления ресурсами файлового дескриптора? Каким бы ни был механизм, похоже, он работает довольно хорошо — как узнать, когда лучше использовать hClose
явно?