PROBLEM:
I am developing a server with Boost and there is an xml file from which some data is loaded by the main thread at initialization.
During execution some changes can happen and should be stored in the xml file. For this purpose a function store() was implemented in a class called Database:
Database::store()
{
boost::mutex::scoped_lock lock(_databaseMutex);
//xml file wirting
}
If I want to store changes from another thread different from the main who created the class Database (a socket connection, for example), xml fails as it seems to be thread unsafe.
Posible solution:
My idea is to create a loop in the server (main thread) waiting for notifications from other threads, something like this:
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();
}
}
This way xml writing does not crash.
Question:
It all depends on what the main thread is doing and how the program is designed and implemented.
The solution you propose will work fine but it hogs a single thread just for processing writes to the xml file.
Are you familiar with boost::asio
?
In any server I would use boost::asio
with either a single thread or a pool of threads calling ioservice::run
. Updates to the xml file are "posted" to the asio event loop and are dispatched / performed by any of the worker threads in its threadpool (i.e. the threads that called ioserive::run). This means that you system uses less threads and the threads it is using are capable to performing numerous asynchronous operations.
Note: boost::asio::post
is used to have a function called within the asio event loop, this allows you to control/serialize access to the xml file
See:
boost::asio
boost::asio::post
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With