2012-11-15 6 views
8

PROBLEMA:soluzione ottima per la memorizzazione di dati in XML thread-safe con Boost

Sto sviluppando un server con Boost e non v'è un file XML da cui alcuni dati vengono caricati dal thread principale in fase di inizializzazione .

Durante l'esecuzione possono verificarsi alcune modifiche che devono essere memorizzate nel file xml. A questo scopo un negozio di funzione() è stato realizzato in una classe chiamata database:

Database::store() 
{ 
    boost::mutex::scoped_lock lock(_databaseMutex); 
    //xml file wirting 
} 

Se voglio archiviare le modifiche da un altro thread diversa dalla principale che ha creato il database di classe (una connessione socket, ad esempio), xml ha esito negativo in quanto sembra essere thread non sicuro. soluzione

Posible:

La mia idea è quella di creare un ciclo nel (thread principale) del server in attesa di notifiche da altri thread, qualcosa di simile:

void loopQueue() 
{ 
    boost::mutex::scoped_lock lock(_queueMutex);  // close the lock  
    while(true) 
    { 
     while (_queuedActions.empty()) 
     { 
      _updateAvailable.wait(lock); 
     }   
     getDatabase(param)->store();  //stores database 
     _queuedActions.pop(); 
    } 
} 

In questo modo la scrittura xml fa non andare in crash.

Domanda:

  • Esiste una soluzione più efficiente o migliore per questo tipo di problema o è questo il modo giusto?

risposta

3

Tutto dipende da cosa sta facendo il thread principale e da come il programma è progettato e implementato.

La soluzione proposta funzionerà correttamente ma esegue il hog di un singolo thread solo per l'elaborazione delle scritture nel file xml.

Hai familiarità con boost::asio?

In qualsiasi server vorrei utilizzare boost::asio con un singolo thread o un pool di thread chiamando ioservice::run. Gli aggiornamenti al file xml vengono "postati" al ciclo di eventi asio e vengono inviati/eseguiti da uno qualsiasi dei thread worker nel suo threadpool (ovvero i thread che hanno chiamato ioserive :: run). Ciò significa che il sistema utilizza meno thread e i thread che sta utilizzando sono in grado di eseguire numerose operazioni asincrone.

Nota: boost::asio::post è usato per avere una funzione chiamata all'interno del ciclo di eventi ASIO, questo consente di controllare/serializzare l'accesso al file xml

See: boost::asio boost::asio::post

+1

Sto leggendo su questo argomento in questo momento, sembra interessante, anche per un thread per connessione. –

+1

Il modo migliore è utilizzare un pool di thread. La generazione di un thread per connessione non viene ridimensionata se il server deve gestire un numero elevato di connessioni diverse (ad esempio, un commutatore VOIP che gestisce migliaia di chiamate). Gli esempi forniti con 'boost :: asio' riguardano sia scenari semplici che complessi, sfortunatamente alcuni degli scenari più complessi non sono spiegati/documentati.Ci sono alcune risorse eccellenti qui, che spiegano diverse tecniche per lo sviluppo di server multi-thread con 'boost :: asio'. IMHO 'boost :: asio' è una delle migliori librerie C++ scritte/più utilizzabili che ho usato. – mark

Problemi correlati