() Yüksek tüm büyük bir dosya
"" İkili dosya (~ 8 GB) aşağıdaki kodu (test.kullanarak yüksek olmaya çalışıyorum c).
#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;
}
test.c gcc -std=c99 test.c -o test
file
kullanarak derlenmiş test verir: test: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
Bu küçük dosyalar için iyi çalışmasına rağmen, büyük bir yük için çalışırken bölümleme hatası alıyorum. Program aslında verir:
Size: 8274324021
mmap: Cannot allocate memory
Tüm dosyasını kullanarak Destek göster başardım::iostreams::mapped_file ama C ve sistem çağrılarını kullanarak yapmak istiyorum. Benim kod yanlış olan nedir?
CEVAP
7* *eşleştirmeleri bu sayfalarda yazılı kopya üzerinde yazma neden olabilir ayırma gibi bir bellek ayırma gerektirir. Bu fiziksel bir şey ram takas daha çok büyük harita anlamına gelir. Bunun yerine MAP_SHARED
bir eşleme kullanmayı deneyin. Eşleme yazar bunun anlamı disk gibi yansır, çekirdek her zaman geri yazma yaparak bellek kadar özgür olabilir bilir, seni sınırlamak istemiyorum.
Ben de PROT_WRITE
, ama o zaman ve bellek eşleme git oku ile harita yapıyorsun unutmayın. Ayrıca O_RDONLY
- Bu sizin için bir sorun olabilir; eğer MAP_SHARED
12 *kullanmak isterseniz O_RDWR
belirtmelisiniz ile dosya açılır.
PROT_WRITE
sadece, bu 86 ve yazma eşleştirmeleri desteklemiyor, ama diğer platformlarda segfaults neden olabilir, çünkü 86, üzerinde çalışmaya başladı. İsteği sadece okumak lazım, 16 ** 15 ** - ya,.
Benim sistem (VPS'İN ile 676MB RAM, 256 MB swap), yeniden sorun; değişen MAP_SHARED
sonuçlar EPERM
hata (beri iznim yok yazmak için yedekleme dosyası açıldı O_RDONLY
). PROT_READ
MAP_SHARED
değiştirme eşleme başarılı olmasını sağlar.
Eğer dosyanın bayt değiştirmek isterseniz, sadece bir seçenek aralıkları için yazacaksın özel yapmak olacaktır. Yani, munmap
MAP_PRIVATE
ile eşleştirmek için yazmak istediğiniz alanlar. Eğer yazmak istiyorsanız tabiitüm dosyasonra hafıza 8 GB bunu yapmak gerekir.
Alternatif olarak, /proc/sys/vm/overcommit_memory
24 *yazabilirsiniz. Bu eşleştirme isteği başarılı olmak için izin verir; ancak, eğer gerçekten İNEK bellek, Programın Tam 8 GB (veya başka bir program!) kullanmayı deneyin unutmayın OOM katil tarafından öldürülecek.
Nasıl Git deposu tarih commit/kaldırma...
En iyi C bayt bir dizi halinde büyük b...
Nasıl Git içinde büyük küçük harf duya...
Hızlı bir Linux sistemi üzerinde büyük...
Ne kadar büyük dosya okumak için pytho...