Use direct IO :
Direct I/O is a feature of the file system whereby file reads and writes go directly from the applications to the storage device, bypassing the operating system read and write caches. Direct I/O is used only by applications (such as databases) that manage their own caches.
An application invokes direct I/O by opening a file with the
O_DIRECT
flag.
Por exemplo:
int fd = open( filename, O_RDONLY | O_DIRECT );
O Direct IO no Linux é peculiar e tem algumas restrições. O buffer de E / S do aplicativo deve ser alinhado à página e alguns sistemas de arquivos exigem que cada solicitação de E / S seja um múltiplo exato do tamanho da página. Essa última restrição pode dificultar a leitura / gravação da última parte de um arquivo.
Uma maneira fácil de codificar para lidar com leitura antecipada em seu aplicativo pode ser feita usando fdopen
e definindo um buffer grande alinhado a página usando posix_memalign
e setvbuf
:
// should really get page size using sysconf()
// but beware of systems with multiple page sizes
#define ALIGNMENT ( 4UL * 1024UL )
#define BUFSIZE ( 1024UL * 1024UL )
char *buffer;
...
int fd = open( filename, O_RDONLY | O_DIRECT );
FILE *file = fdopen( fd, "rb" );
int rc = posix_memalign( &buffer, ALIGNMENT, BUFSIZE );
rc = setvbuf( file, buffer, _IOFBF, BUFSIZE );
Você também pode usar mmap()
para obter memória anônima para usar o buffer. Isso tem a vantagem de ser naturalmente alinhado à página:
...
char *buffer = mmap( NULL, BUFSIZE, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0 );
rc = setvbuf( file, buffer, _IOFBF, BUFSIZE );
Em seguida, use apenas fread()
/ fgets()
ou qualquer função de leitura FILE *
-type que você deseja ler no fluxo file
.
Você precisa verificar usando uma ferramenta como strace
que as chamadas do sistema read
reais são feitas com um buffer alinhado à página e com tamanho de página - algumas implementações da biblioteca C de FILE *
-based processing don Não use o buffer especificado por setvbuf
para apenas buffer de E / S, para que o alinhamento e o tamanho possam ser desativados. Eu não acho que o Linux / glibc faz isso, mas se você não verificar e o tamanho e / ou alinhamento estiverem desativados, suas chamadas de IO falharão.
E novamente - Linux IO direto pode ser peculiar. Apenas alguns sistemas de arquivos suportam IO direto, e alguns deles são mais específicos que outros. TESTE completamente se você decidir usá-lo.
O código postado fará uma leitura antecipada de 1 MB sempre que o buffer do fluxo precisar ser preenchido. Você também pode implementar uma leitura antecipada mais sofisticada usando threads - um thread preenche um buffer, outro thread (s) é lido de um buffer completo. Isso evitaria o processamento de "gaguejos" à medida que a leitura antecipada é feita, mas ao custo de uma boa quantidade de código multithreading relativamente complexo.