Domanda

Voglio realizzare una semplice classe per l'accesso da più thread. L'idea che ci sia, che ogni oggetto che vuole accedere roba, riceve un ostream-oggetto che si può scrivere messaggi a utilizzare gli operatori abituali. Il comportamento desiderato è, che i messaggi vengono aggiunti al registro quando il flusso viene svuotata. In questo modo, i messaggi non verrà interrotto da messaggi da altri thread. Voglio evitare di utilizzare uno stringstream temporanea per memorizzare il messaggio, come che renderebbe maggior parte dei messaggi almeno i twoliners. Come la vedo io, il modo standard di raggiungere questo sarebbe quello di implementare il mio streambuffer, ma questo sembra molto ingombrante e soggetto a errori. C'è un modo più semplice per fare questo? In caso contrario, non si conosce un buon articolo / howto / guide su streambuf personalizzati?

Grazie in anticipo,

Space_C0wbo0y

UPDATE:

Dal momento che sembra funzionare ho aggiunto la mia risposta.

È stato utile?

Soluzione 2

Così, ho preso uno sguardo al Boost.IOstreams ecco quello che è venuta in mente:

class TestSink : public boost::iostreams::sink {
public:
    std::streamsize write( const char * s, std::streamsize n ) {
        std::string message( s, n );
            /* This would add a message to the log instead of cout.
               The log implementation is threadsafe. */
        std::cout << message << std::endl;
        return n;
    }
};

TestSink può essere usato per creare un flusso-buffer (vedi stream_buffer-template ). Ogni filo riceverà essa la propria istanza di TestSink, ma tutti TestSinks scriverà sullo stesso registro. TestSink è utilizzato come segue:

TestSink sink;
boost::iostreams::stream_buffer< TestSink > testbuf( sink, 50000 );
std::ostream out( &testbuf );

for ( int i = 0; i < 10000; i++ )
    out << "test" << i;

out << std::endl;

Il fatto importante è che TestSink.write viene chiamato solo quando il flusso viene svuotata (std::endl o std::flush), o quando il buffer interno dell'istanza stream_buffer è pieno (la dimensione del buffer predefinito non può contenere 40000 caratteri, quindi inizializzare essa a 50000). In questo programma, TestSink.write si chiama esattamente una volta (l'uscita è troppo lungo per postare qui). In questo modo posso scrivere messaggiodilog con una normale formattato stream-IO senza variabili temporanee ed essere sicuri, che il messaggio viene inviato al log in un unico pezzo, quando ho lavare il flusso.

Vi lascio la questione aperta un altro giorno, nel caso in cui ci sono diversi suggerimenti / problemi non ho considerato.

Altri suggerimenti

Date un'occhiata a log4cpp ; essi hanno un supporto multi-thread. Può salvare il vostro tempo.

Pensi log4cpp è troppo pesante e si raggiunge per Boost.IOStreams invece? Eh?

Si potrebbe desiderare di prendere in considerazione logog . E 'thread-safe per POSIX, Win32 e Win64.

Re. la propria risposta. Se si utilizza questo per la registrazione degli errori e si programma si blocca prima del lavaggio vostro flusso allora la registrazione è un po 'inutile, non è vero?

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