C 如果不取消映射,则无法关闭内存映射文件,因为它';它仍然被引用

C 如果不取消映射,则无法关闭内存映射文件,因为它';它仍然被引用,c,macos,system-calls,mmap,C,Macos,System Calls,Mmap,我在macOS中遇到了这样一个场景:我无法关闭内存映射文件,而没有 首先取消映射它(使用munmap syscall),尽管close syscall返回成功结果(=0),我仍然可以在lsof-n中看到文件记录 在linux中,根据mmap手册页,明确提到关闭文件不会取消文件映射 这两个操作系统之间的行为确实不同吗? 这种不同的行为有什么解释吗 编辑:在阅读了下面的评论之后,我意识到平台之间没有不同的行为,我的文件仍然打开的原因是它仍然被mmap引用 谢谢要求即使在关闭后也要有对mmap'ed文

我在macOS中遇到了这样一个场景:我无法关闭内存映射文件,而没有 首先取消映射它(使用munmap syscall),尽管close syscall返回成功结果(=0),我仍然可以在
lsof-n
中看到文件记录

在linux中,根据mmap手册页,明确提到关闭文件不会取消文件映射

这两个操作系统之间的行为确实不同吗? 这种不同的行为有什么解释吗

编辑:在阅读了下面的评论之后,我意识到平台之间没有不同的行为,我的文件仍然打开的原因是它仍然被mmap引用

谢谢

要求即使在关闭后也要有对mmap'ed文件的引用

mmap()函数应向与文件描述符fildes关联的文件添加额外的引用,该文件描述符上的后续close()不会删除该文件。当没有更多映射到文件时,应删除此引用


这就是
lsof
看到的,有一个对该文件的引用。因此,它的工作原理是有据可查的。

是不是Linux和MacOS在应用程序中的使用模式有所不同?我希望在文件实际关闭之前,关闭和取消映射文件是必要的。Linux可能对顺序漠不关心,但MacOS可能关心先做哪个。由于mmap,该文件仍在使用中。。。你所做的就是关闭adescriptor。你在Linux上测试过它吗?在
lsof-n
output@anttihaapala,不,我只是假设它是根据他们的手册页工作的,但是根据下面的答案,这种行为似乎是合理的。你如何描述Linux和Mac之间的区别?在这两种情况下,关闭文件不会取消映射。在这两种情况下,(成功)
close()
调用后,打开的文件描述将保留在系统中。或者至少这是我所期望的,而且似乎与您所说的一致。我的过程实际上是打开装入点中的所有文件,映射它们,然后关闭它们。因此,当在不首先取消映射的情况下关闭文件时,我会收到“系统中打开的文件过多”消息。所以现在我知道这是意料之中的。。但是,如果在关闭后尝试根据文件描述符取消映射,该怎么办?@Zohar81:open()会增加文件的引用计数。mmap()也是(现在有两个参考文献);close()将其递减(现在为:1)。在munmap()之后,计数将降至零。您可以尝试在您的系统上执行此操作。显然,您不希望有太多映射文件或打开文件描述符。关闭文件不会直接链接到取消映射同一文件。您可以在映射后立即关闭它。然后在需要时将其映射。@Zohar81,在任何情况下,如何使用文件描述符来取消映射文件
munmap()
要求您指定映射的地址,以确定要取消映射的内容。但是,如果您确实以这种方式取消映射文件,那么是的,这将释放一个打开的文件描述槽。@约翰伯林格,您是对的,我需要使用第一次映射文件时返回的地址。。。fd在这里帮不上忙。