SORU
28 AĞUSTOS 2011, Pazar


() 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
28 AĞUSTOS 2011, Pazar


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.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • ethr95awd

    ethr95awd

    8 Kasım 2006
  • Maschine Tutorials

    Maschine Tut

    15 ŞUBAT 2011
  • Matt Stokes

    Matt Stokes

    22 Ocak 2008