Rust 用所有权管理文件描述符:drop 就关闭。这篇用真实的 fd 计数验证每一种情形 —— 正常释放、泄漏、上限、克隆、移交给裸 fd、重复关闭,以及子进程继承。
编译:成功
运行(退出码 0):
打开 1 个文件:fd = 3,进程里打开的 fd 数 4 → 5
再打开 1 个:fd = 4,数量 6
drop(f1) 之后数量 5
再开一个,拿到的 fd = 3(复用了刚释放的编号)
块内再开一个,数量 7
块结束(自动 drop)之后数量 6Drop 的规则见Drop Trait 与资源释放;文件读写见std::fs 文件读写。
编译:成功
运行(退出码 0):
RLIMIT_NOFILE 软限制 = 1048576(getrlimit 报告的值)
第 61438 次 open 失败:kind = TooManyOpenFiles,os_error = Some(24),Too many open files (os error 24)
一共成功打开 61437 个(加上进程启动时已有的 stdin/out/err 等)
释放 10 个之后再 open: 成功上限在不同系统与配置下不同;这里 getrlimit 返回的值与实际失败点不一致,原因没有深究。
编译:成功
运行(退出码 0):
每轮函数结束时 File 被 drop:处理了 1000 / 1000 个,结束后 fd 数 4
mem::forget 让 fd 泄漏:打开了 1000 个并忘记关闭,结束后 fd 数 1004(从 4 涨到 1004,一个都没有回收) 编译:成功
运行(退出码 0):
try_clone:原 fd = 3,克隆 fd = 4(不同编号,指向同一个打开的文件),数量 2
原 File 已 drop,克隆仍然可读:"hello"
into_raw_fd 得到 fd 3:File 已经被消耗,但 fd 仍然打开(数量 2),要自己关闭
手动 close 两次:第一次返回 0,第二次返回 -1(-1 = EBADF:fd 已经关了)
OwnedFd::from_raw_fd 重新交给 Rust 管理:数量 2
drop(OwnedFd) 之后数量 1裸指针的类似 into_raw / from_raw 见原始指针解引用。
编译:成功
运行(退出码 0):
child has no fd 3 (not inherited)子进程见子进程与 Command。