2013-08-12 13 views

risposta

24

Dato che ci si è collegati ai 2.7 documenti, presumo che si stia utilizzando 2.7. (In Python 3.x, tutto diventa molto più semplice, perché molto più del buffering è esposto a livello di Python.)

Tutto lo open in realtà (su sistemi POSIX) è chiamare fopen, e quindi, se hai passato nulla per buffering, setvbuf. Dato che non stai passando nulla, finisci con il buffer predefinito da fopen, che dipende dalla tua libreria C standard. (.. Vedere the source per i dettagli Senza buffering, passa da -1 a PyFile_SetBufSize, che non fa nulla se non bufsize >= 0)

Se leggete il glibc setvbuf manpage, si spiega che se non si chiama una delle funzioni di buffering:

Normalmente tutti i file sono bloccati in blocchi. Quando si verifica la prima operazione di I/O su un file, viene chiamato malloc (3) e viene ottenuto un buffer.

Si noti che non viene specificato il buffer di dimensione. Questo è intenzionale; significa che l'implementazione può essere intelligente e scegliere diverse dimensioni del buffer per casi diversi. (C'è una costante BUFSIZ, ma che viene utilizzato solo quando si chiamano funzioni legacy come setbuf;. Non è garantito per essere utilizzato in tutti gli altri casi)

Allora, che cosa vuol accada? Bene, se si guarda alla fonte glibc, alla fine si chiama la macro _IO_DOALLOCATE, che può essere agganciata (o sovrascritta, perché glibc unifica C++ streambuf e C stdio buffering), ma alla fine assegna un buf di _IO_BUFSIZE, che è un alias per la macro specifica della piattaforma _G_BUFSIZE, che è 8192.

Ovviamente probabilmente si desidera rintracciare le macro sul proprio sistema piuttosto che fidarsi della sorgente generica.


Ci si potrebbe chiedere perché non ci sia un buon modo documentato per ottenere queste informazioni. Presumibilmente è perché non dovresti preoccuparti. Se hai bisogno di una dimensione specifica del buffer, ne imposti manualmente una; se ti fidi che il sistema sappia che è meglio, fidati. A meno che tu non stia davvero lavorando al kernel o alla libc, a chi importa? In teoria, ciò lascia anche aperta la possibilità che il sistema possa fare qualcosa di intelligente qui, come scegliere un bufsize basato sulla dimensione del blocco per il filesystem del file, o anche sulla base di dati statistici in esecuzione, sebbene non assomigli a linux/glibc , FreeBSD o OS X fanno qualcosa di diverso da usare una costante. E probabilmente è perché non importa per la maggior parte delle applicazioni. (Potresti testarlo tu stesso - usa le dimensioni del buffer esplicito che vanno da 1KB a 2MB su alcuni script con I/O bufferizzato e vedi quali sono le differenze nelle prestazioni.)

+0

Grande spiegazione abarnert! Grazie. – falconepl

-1
#include <stdio.h> 

int main(int argc, char* argv[]){ 
    printf("%d\n", BUFSIZ); 
    return 0; 
} 

Ho fatto "man setvbuf" per trovare questo. setvbuf è la nota [2] della pagina della documentazione.

+0

No, non è garantito di essere la dimensione del buffer di default; è solo la dimensione del buffer utilizzata per le funzioni legacy come 'setbuf'. – abarnert

+0

Se questo è il caso, l'argomento non è molto utile: [2] \t Specificare una dimensione del buffer non ha alcun effetto sui sistemi che non hanno setvbuf(). L'interfaccia per specificare la dimensione del buffer non viene eseguita utilizzando un metodo che chiama setvbuf(), poiché potrebbe eseguire il dump di un core quando viene chiamato dopo che è stato eseguito un I/O e non esiste un modo affidabile per determinare se questo è il caso. – seanmcl

+0

Quale argomento? E quale sistema sei su dove 'setvbuf (3)' ha note a piè di pagina? Terzo, [CPython 2.7 chiama molto chiaramente 'setbuf'] (http://hg.python.org/cpython/file/2.7/Objects/fileobject.c#l509) se' setvbuf' non è disponibile, quindi non è vero che non ha alcun effetto. (È vero che qualsiasi valore positivo ha lo stesso effetto di qualsiasi altro valore positivo sui sistemi "setbuf'-only, ma non è ancora sicuramente _no_ effect.) E, infine, chiama chiaramente" setvbuf' è se è disponibile, quindi il tuo l'argomento che non può farlo è discutibile. – abarnert

11

io non sono sicuro che sia la risposta giusta, ma python 3.0 library e python 20 library sia descrivono io.DEFAULT_BUFFER_SIZE nello stesso modo che il default è descritto nella documentazione per open(). Coincidenza?

Se no, allora la risposta per me è stato:

$ python 
>>> import io 
>>> io.DEFAULT_BUFFER_SIZE 
8192 

$ lsb_release -a 
No LSB modules are available. 
Distributor ID: Ubuntu 
Description: Ubuntu 14.04.1 LTS 
Release:  14.04 
Codename:  trusty 
Problemi correlati