标签: mmap

我什么时候应该使用mmap进行文件访问?

POSIX环境提供至少两种访问文件的方法.有标准的系统调用open(),read(),write(),和朋友,但也有使用的选项mmap(),将文件映射到虚拟内存.

何时优先使用一个而不是另一个?它们各自的优势是什么,包括两个接口?

c file-io posix mmap

263
推荐指数
6
解决办法
10万
查看次数

mmap()与阅读块

我正在开发一个程序,该程序将处理可能大小为100GB或更大的文件.这些文件包含一组可变长度记录.我已经启动并运行了第一个实现,现在我正在寻求提高性能,特别是在输入文件被多次扫描时更有效地进行I/O.

mmap()通过C++的fstream库使用和读取块有经验吗?我想做的是从磁盘读取大块到缓冲区,从缓冲区处理完整记录,然后阅读更多.

mmap()代码可能会变得非常凌乱,因为mmap"d块需要躺在页大小的边界(我的理解)和记录可能潜在般划过页面边界.使用fstreams,我可以寻找记录的开头并再次开始阅读,因为我们不仅限于阅读位于页面大小边界的块.

如何在不实际编写完整实现的情况下决定这两个选项?任何经验法则(例如,mmap()快2倍)或简单测试?

c++ file-io fstream mmap

172
推荐指数
6
解决办法
7万
查看次数

当项目中包含程序集文件时,mmap产生了意外的执行权限

我正在用这个把我的头撞到墙上。

在我的项目中,使用mmap映射(/proc/self/maps)分配内存时,尽管我只请求了可读内存,但它仍是一个可读且可执行的区域。

在研究了strace(看起来不错)和其他调试之后,我能够确定似乎唯一可以避免这个奇怪问题的东西:从项目中删除程序集文件,只保留纯C。(什么?!)

所以这是我一个奇怪的例子,我正在使用Ubunbtu 19.04和默认的gcc。

如果使用ASM文件(为空)编译目标可执行文件,则将mmap返回一个可读和可执行区域,如果构建时没有该区域,则它将正常运行。请参阅/proc/self/maps示例中已嵌入的输出。

example.c

#include <stdio.h>
#include <string.h>
#include <sys/mman.h>

int main()
{
    void* p;
    p = mmap(NULL, 8192,PROT_READ,MAP_ANONYMOUS|MAP_PRIVATE,-1,0);

    {
        FILE *f;
        char line[512], s_search[17];
        snprintf(s_search,16,"%lx",(long)p);
        f = fopen("/proc/self/maps","r");
        while (fgets(line,512,f))
        {
            if (strstr(line,s_search)) fputs(line,stderr);
        }

        fclose(f);
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

example.s:是一个空文件!

产出

附带ASM版本

VirtualBox:~/mechanics/build$ gcc example.c example.s -o example && ./example
7f78d6e08000-7f78d6e0a000 r-xp 00000000 00:00 0 
Run Code Online (Sandbox Code Playgroud)

没有ASM随附的版本

VirtualBox:~/mechanics/build$ gcc example.c -o example && ./example
7f1569296000-7f1569298000 …
Run Code Online (Sandbox Code Playgroud)

c linux assembly mmap

94
推荐指数
2
解决办法
2506
查看次数

Mmap()一个完整的大文件

我正在尝试使用以下代码(test.c)"mmap"二进制文件(~8Gb).

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define handle_error(msg) \
  do { perror(msg); exit(EXIT_FAILURE); } while (0)

int main(int argc, char *argv[])
{
   const char *memblock;
   int fd;
   struct stat sb;

   fd = open(argv[1], O_RDONLY);
   fstat(fd, &sb);
   printf("Size: %lu\n", (uint64_t)sb.st_size);

   memblock = mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, fd, 0);
   if (memblock == MAP_FAILED) handle_error("mmap");

   for(uint64_t i = 0; i < 10; i++)
   {
     printf("[%lu]=%X ", i, memblock[i]);
   }
   printf("\n");
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

test.c是使用 …

c mmap

64
推荐指数
2
解决办法
4万
查看次数

Linux共享内存:shmget()vs mmap()?

这个线程中,建议使用OP mmap()而不是shmget()在Linux中获取共享内存.我访问了这个页面和这个页面以获得一些文档,但第二个给出了一个模糊的例子mmap().

几乎是一个新手,并且需要在两个进程之间共享一些信息(以文本形式),我应该使用该shmget()方法还是mmap()?为什么?

c linux posix mmap shared-memory

55
推荐指数
2
解决办法
5万
查看次数

malloc实现是否会将free-ed内存返回给系统?

我有一个长期存在的应用程序,频繁的内存分配 - 释放.任何malloc实现都会将释放的内存返回给系统吗?

在这方面,什么是以下行为:

  • ptmalloc 1,2(默认为glibc)或3
  • dlmalloc
  • tcmalloc(谷歌线程malloc)
  • solaris 10-11默认malloc和mtmalloc
  • FreeBSD 8默认malloc(jemalloc)
  • Hoard malloc?

更新

如果我有一个应用程序,其白天和夜晚的内存消耗可能非常不同(例如),我可以强制任何malloc将系统释放的内存吗?

如果没有这样的返回,释放的内存将被多次换出,但这样的内存只包含垃圾.

malloc free mmap glibc tcmalloc

54
推荐指数
4
解决办法
2万
查看次数

在调用mmap之后我是否需要保持文件打开?

我有一个程序可以映射相当多的(100个)大小的文件,每个文件10-100MB.我需要它们全部同时映射.

目前我打电话open,然后mmap在程序,随后开始munmapclose结尾.

通常我必须ulimit -n在运行程序之前调整打开的文件限制.

问题是我实际上需要保持文件打开,或者我可以在完成后open mmap close进行一些大数据处理munmap.

的手册页mmap似乎并不非常清楚,我在这一个.

c mmap

54
推荐指数
1
解决办法
1万
查看次数

在Mac上设置Laravel php artisan migrate错误:没有这样的文件或目录

  1. 将一个完美工作的laravel项目从一个git拉到一个运行MAMP的mac上.项目在linux机器上完美运行.
  2. 作曲家安装
  3. php artisan migrate,出现以下错误:

    [PDOException]                                    
    SQLSTATE[HY000] [2002] No such file or directory 
    
    Run Code Online (Sandbox Code Playgroud)

注意:php -v是5.5,mysql -v是终端的5.5这是我的config/database.php的一部分

    'mysql' => array(
        'driver'    => 'mysql',
        'host'      => 'localhost',
        'database'  => 'essays',
        'username'  => 'root',
        'password'  => 'root',
        'charset'   => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix'    => '',
    ),
Run Code Online (Sandbox Code Playgroud)

我尝试用127.0.0.1替换localhost但没有用.请帮忙..

编辑: 我在php.ini中添加了这三行

mysql.default_socket = /var/run/mysqld/mysqld.sock

mysqli.default_socket = /var/run/mysqld/mysqld.sock

pdo_mysql.default_socket = /var/run/mysqld/mysqld.sock
Run Code Online (Sandbox Code Playgroud)

我还添加了这个符号链接:

sudo mkdir /var/mysql
cd /var/mysql && sudo ln -s /Applications/XAMPP/xamppfiles/var/mysql/mysql.sock
Run Code Online (Sandbox Code Playgroud)

但那并没有解决.我也是从混帐拉一个全新的laravel项目后遇到同样的错误composer install,然后php artisan migrate

 [PDOException]                                    
  SQLSTATE[HY000] [2002] No such file …
Run Code Online (Sandbox Code Playgroud)

php mysql mmap laravel

45
推荐指数
7
解决办法
7万
查看次数

为什么Python的mmap不适用于大文件?

[编辑:此问题仅适用于32位系统.如果你的计算机,你的操作系统和你的python实现是64位的,那么mmap-ing巨大的文件可以正常工作并且非常高效.

我正在编写一个模块,其中包括允许按位读取文件访问.这些文件可能很大(数百GB),所以我编写了一个简单的类,让我像处理字符串一样处理文件并隐藏所有的搜索和阅读.

当我写我的包装类时,我不知道mmap模块.在阅读mmap的文档时,我认为"很棒 - 这正是我所需要的,我将取出我的代码并用mmap替换它.它可能效率更高,删除代码总是好的."

问题是mmap不适用于大文件!这对我来说非常令人惊讶,因为我认为它可能是最明显的应用程序.如果文件超过几千兆字节,那么我得到一个EnvironmentError: [Errno 12] Cannot allocate memory.这只发生在32位Python构建中,所以它似乎耗尽了地址空间,但我找不到任何关于此的文档.

我的代码就是

f = open('somelargefile', 'rb')
map = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
Run Code Online (Sandbox Code Playgroud)

所以我的问题是我错过了一些明显的东西吗?有没有办法让mmap可以在大文件上移植,或者我应该回到我天真的文件包装器?


更新:似乎有一种感觉,Python mmap应该具有与POSIX mmap相同的限制.为了更好地表达我的挫败感,这是一个简单的类,它具有mmap的一小部分功能.

import os

class Mmap(object):
    def __init__(self, f):
        """Initialise with a file object."""
        self.source = f

    def __getitem__(self, key):
        try:
            # A slice
            self.source.seek(key.start, os.SEEK_SET)
            return self.source.read(key.stop - key.start)
        except AttributeError:
            # single element
            self.source.seek(key, os.SEEK_SET)
            return self.source.read(1)
Run Code Online (Sandbox Code Playgroud)

它是只读的,并没有做任何花哨的事情,但我可以像使用mmap一样:

map2 = Mmap(f)
print map2[0:10]
print map2[10000000000:10000000010]
Run Code Online (Sandbox Code Playgroud)

除了文件大小没有限制.真的不太难......

python memory performance mmap

44
推荐指数
5
解决办法
3万
查看次数

加速文件I/O:mmap()与read()

我有一个Linux应用程序,并行读取150-200个文件(4-10GB).每个文件依次以小的,可变大小的块读取,每个块通常小于2K.

我目前需要从文件集中保持超过200 MB/s的读取速率.磁盘处理这个很好.预计需要超过1 GB/s(目前不在磁盘范围内).

我们已经实现了两个不同的读取系统,它们都大量使用posix_advise:首先是mmaped读取,其中我们映射整个数据集并按需读取.第二个是基于read()/ seek()的系统.

两者都运行良好但仅适用于中等情况,该read()方法更好地管理我们的整体文件缓存并且可以很好地处理100 GB的文件,但是速率受限,mmap能够预先缓存数据使得持续数据速率超过200MB/s易于维护,但无法处理较大的总数据集大小.

所以我的问题来自于:

答:可以在Linux read()posix_advise调用之外进一步优化类型文件i/o ,或者调整磁盘调度程序,VMM和posix_advise调用是否符合我们的预期?

B:有没有系统的方法让mmap更好地处理非常大的映射数据?

Mmap-vs-reading-blocks 与我正在工作的问题类似,并且提供了一个关于这个问题的良好起点,以及mmap-vs-read中的讨论.

c c++ file-io mmap

44
推荐指数
2
解决办法
9821
查看次数

标签 统计

mmap ×10

c ×6

file-io ×3

c++ ×2

linux ×2

posix ×2

assembly ×1

free ×1

fstream ×1

glibc ×1

laravel ×1

malloc ×1

memory ×1

mysql ×1

performance ×1

php ×1

python ×1

shared-memory ×1

tcmalloc ×1