Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 写入文件和映射内存之间有什么区别?_C_Linux_File_Mmap - Fatal编程技术网

C 写入文件和映射内存之间有什么区别?

C 写入文件和映射内存之间有什么区别?,c,linux,file,mmap,C,Linux,File,Mmap,我有以下与处理文件和映射文件相关的问题(mmap): 我们知道,如果我们创建一个文件并写入该文件,那么无论哪种方式,我们都在写入内存。那么为什么要使用mmap将该文件映射到内存,然后写入 如果是因为使用mmap-PROT\u NONE、PROT\u READ、PROT\u WRITE实现了保护,那么使用文件也可以实现相同级别的保护O_RDONLY,O_RDWR等等。那为什么mmap 将文件映射到内存,然后使用它,有什么特别的优势吗?而不仅仅是创建一个文件并写入它 最后,假设我们mmap将一个文件

我有以下与处理文件和映射文件相关的问题(
mmap
):

  • 我们知道,如果我们创建一个文件并写入该文件,那么无论哪种方式,我们都在写入内存。那么为什么要使用
    mmap
    将该文件映射到内存,然后写入
  • 如果是因为使用
    mmap
    -
    PROT\u NONE
    PROT\u READ
    PROT\u WRITE
    实现了保护,那么使用文件也可以实现相同级别的保护
    O_RDONLY
    O_RDWR
    等等。那为什么
    mmap
  • 将文件映射到内存,然后使用它,有什么特别的优势吗?而不仅仅是创建一个文件并写入它
  • 最后,假设我们
    mmap
    将一个文件写入内存,如果我们写入mmap返回的内存位置,它是否也同时写入该文件
  • 编辑:在线程之间共享文件 据我所知,如果我们在两个线程(不是进程)之间共享一个文件,那么建议
    mmap
    将其放入内存然后使用,而不是直接使用该文件


    但我们知道,使用文件意味着,它肯定在主内存中,那么为什么还要再次对线程进行MMA?

    内存映射文件实际上部分或全部映射到内存(RAM),而您写入的文件将写入内存,然后刷新到磁盘。内存映射文件从磁盘中取出,并显式地放入内存中进行读取和/或写入。它会一直保持在那里,直到你解开它

    对磁盘的访问速度较慢,因此当您写入文件时,它将被刷新到磁盘,不再驻留在RAM中,这意味着,下一次您需要该文件时,您可能会从磁盘获取它(速度较慢),而在内存映射文件中,您知道该文件位于RAM中,并且可以比在磁盘上时更快地访问它

    此外,mememory映射文件通常用作IPC机制,因此两个或多个进程可以轻松共享同一文件并对其进行读/写。(使用必要的sycnh机制)

    当您需要经常读取一个文件,并且该文件相当大时,最好将其映射到内存中,这样您就可以更快地访问它,然后每次都必须打开它并从磁盘获取它

    编辑:

    这取决于您的需要,当您有一个文件需要由不同线程频繁访问时,我不确定内存映射该文件是否一定是一个好主意,因为如果您希望写入该mmap文件,您需要同步访问该文件,在相同的地方从不同的线程。如果这种情况经常发生,它可能成为资源争用的场所

    只要从文件中读取,这可能是一个很好的解决方案,因为如果您仅从多个线程中读取,则实际上不需要同步访问。当你开始写作时,你必须使用同步机制

    我建议您让每个线程以线程本地方式访问自己的文件,如果您必须写入文件,就像处理其他文件一样。通过这种方式,它减少了线程同步的需要,减少了难以发现和调试的bug的可能性

  • 一个原因可能是您有(遗留)代码,该代码被设置为写入数据缓冲区,然后该缓冲区在最后一次写入文件。在这种情况下,使用
    mmap
    将至少保存一份数据副本,因为操作系统可以直接将缓冲区写入磁盘。 只要它只是关于文件编写,我(还)无法想象您为什么要使用
    mmap

  • 不,我想说,这种保护在这里是不相关的

  • 它可能会保存一个或两个数据副本,例如从app buffer到libc buffer再到OS buffer,参见第1点。在写入大量数据时,这可能会影响性能

  • 不可以。据我所知,只要在调用该内存区域上的
    msync
    munmap
    后数据已写入磁盘,操作系统就可以随时自由写入数据。 (对于大多数文件,由于性能原因,在大多数时间间隔内,它很可能不会写入任何内容:将整个块写入磁盘是因为更改一个字节相当昂贵,特别是如果预计在不久的将来会对该块进行更多的修改的话。)

  • 1) 您误解了write(2)系统调用。write()不写,它只是将缓冲区内容复制到操作系统缓冲区链,并将其标记为脏。其中一个操作系统线程(bdflush IIRC)将拾取这些缓冲区,将它们写入磁盘,并摆弄一些标志。稍后。 使用mmap,您可以直接访问操作系统缓冲区(但如果更改其内容,也会将其标记为脏)

    2) 这不是关于保护,而是关于在pagetable条目中设置标志

    3) 避免双重缓冲。此外,您还可以根据字符而不是块来寻址文件,这有时更为实用

    4) 这是您一直在使用的系统缓冲区(连接到您的地址空间)。系统可能有也可能没有将部分内容写入磁盘


    5)如果线程属于同一进程并共享页面和地址空间,则是。

    在大多数情况下,应该将内存映射文件视为您使用的内存。您应该只关心特殊情况,如与光盘同步。它与内存是同一种存储,但可以根据需要从文件初始化并存储到文件。

    那么,我们的优势是什么?您依赖操作系统内存管理机制的优势。您的文件将被放入虚拟内存,操作系统可以将其交换到光盘(不是交换到自己的内存,而是交换到光盘上的映射文件)。因此,您将使用posib实现半永久性存储