Domanda

Sto scrivendo un semplice programma C su Linux e desiderano utilizzare le API di una libreria esistente, che si aspetta i dati da un file. Devo dargli da mangiare un nome di file come un const char *. Ma ho i dati, proprio come il contenuto di un file, già seduto in un buffer allocato sul mucchio. C'è un sacco di RAM e vogliamo ad alte prestazioni. Volendo evitare di scrivere un file temporaneo sul disco, quello che è un buon modo per alimentare i dati a questa API in un modo che assomiglia a un file?

Ecco una versione a basso costo di finzione del mio codice:

marvelouslibrary.h:

int marvelousfunction(const char *filename);

normali-persone-usage.cpp, per il quale biblioteca è stata originariamente concepito:

#include "marvelouslibrary.h"
int somefunction(char *somefilename)
{
    return marvelousfunction(somefilename);
}

myprogram.cpp:

#include "marvelouslibrary.h"
int one_of_my_routines() 
{
    byte* stuff = new byte[1000000];
    // fill stuff[] with...stuff!
    // stuff[] holds same bytes as might be found in a file

    /* magic goes here: make filename referring to stuff[] */

   return marvelousfunction( ??? );
}

Per essere chiari, il marvelouslibrary non dispone di funzioni API che accettano i dati dal puntatore; si può solo leggere un file.

Ho pensato di tubi e mkfifo (), ma sembra dire per la comunicazione tra processi. Non sono un esperto in queste cose. Fa un lavoro named pipe a posto letto e scritto nello stesso processo? E 'questo un approccio saggio?

o saltare essendo intelligente, andare con il piano "B", che è quello di shuddup e basta scrivere un file temporaneo. Tuttavia, mi piacerebbe imparare qualcosa di nuovo e scoprire che cosa è possibile in questa situazione, accanto a ottenere elevate prestazioni.

È stato utile?

Soluzione

Dato che probabilmente hai una funzione come:

char *read_data(const char *fileName)

Credo che è necessario "ignorare di essere intelligente, andare con il piano 'B', che è quello di shuddup e basta scrivere un file temporaneo."

Se si riesce a scavare intorno e scoprire se la chiamata si stanno facendo chiama un'altra funzione che prende un file * o un int per il descrittore di file allora si può fare qualcosa di meglio.

Un pensiero che non mi vengono in mente, si può cahnge il codice per scrivere in un file mappato memoria anziché al mucchio? In questo modo si avrebbe un file su disco già e si eviterebbe la copia (anche se sarà ancora sul disco) e si può ancora dare la funzione di chiamare il nome del file.

Altri suggerimenti

Non sono sicuro di che tipo di ingresso della funzione di libreria vuole ... ne ha bisogno un percorso / nome del file, o il puntatore file aperto, o descrittore di file aperto?

Se non si vuole incidere la biblioteca e la funzione vuole una stringa (percorso di un file), provare a fare il file temporaneo in / dev / shm.

In caso contrario, mmap potrebbe essere l'opzione migliore, si prega di essere sicuri di ricerca posix_madvise () quando si usa mmap () (o il suo omologo posix_fadvise () se si utilizza un file temporaneo).

Sembra che il vostro parlare molto pochi dati per cominciare, quindi non credo che vedrete un impatto sulle prestazioni in qualunque percorso si prende.

Modifica

Mi dispiace, ho appena riletto la tua domanda .. forse ho appena letto troppo veloce. Non c'è modo si sta andando ad alimentare una funzione come:

char * foo(const char *filepath)

... con mmap ().

Se non è possibile modificare la libreria di accettare un descrittore di file al posto (o come alternativa al percorso) .. basta usare / dev / shm e un file temporaneo, sarà abbastanza a buon mercato.

Sei su Linux, non puoi semplicemente afferrare la fonte della biblioteca e incidere nella funzione è necessario? Se è utile agli altri, si potrebbe anche inviare una patch per l'autore originale, in modo che sarà in futuro versioni per tutti.

Modifica Spiacenti. Basta leggere la domanda. Con il mio consiglio di seguito, è fork di un processo di ricambio, e la questione di "non lavori in un unico processo non salire". Ho anche vedo alcun motivo non si poteva generare un thread separato per fare la spinta ...


Per niente elegante, ma si potrebbe:

  1. aprire una named pipe.
  2. fork una banderuola che non fa altro che cercare di scrivere al tubo
  3. passare il nome del tubo

, che dovrebbe essere abbastanza robusto ...

mmap (), forse?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top