|
Boost Users : |
Subject: [Boost-users] Waiting for a thread on another thread
From: Daniel Lidström (daniel.lidstrom_at_[hidden])
Date: 2010-03-05 10:22:19
Hello!
I have created a simple file logger using the active object pattern. This is intended to
offload logging operations to a separate thread, to not disturb the main thread with time-
consuming file operations. It works very nicely with boost::thread, but now I have a new
desired functionality. The file logger keeps an internal queue of strings that need to be
written to file. I want to know, from the main thread, when this queue is empty. To illustrate
I have created a minimal, hopefully compilable, sample that shows what I am trying to achieve.
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/thread/condition.hpp>
#include <boost/foreach.hpp>
#include <boost/tr1/functional.hpp>
#include <vector>
#include <fstream>
#include <string>
class FileLogger
{
typedef boost::unique_lock<boost::mutex> unique_lock;
std::ofstream logfile;
bool running;
boost::thread running_thread;
boost::mutex mutex;
boost::condition_variable condition;
std::vector<std::string> queue;
public:
FileLogger(const std::string& filename)
: logfile(filename.c_str())
, running(true)
, running_thread(std::tr1::bind(&FileLogger::Run, this))
{ }
~FileLogger()
{
running = false;
condition.notify_one();
running_thread.join();
}
void Log(const std::string& s)
{
unique_lock lock(mutex);
queue.push_back(s);
}
void WaitForQueueFlush()
{
// ??
}
private:
void Run()
{
while( running ) {
std::vector<std::string> copyList;
{
// wait 0.1 s here, for queue to fill up
boost::xtime sleepTime;
boost::xtime_get(&sleepTime, boost::TIME_UTC);
sleepTime.nsec += 100*1000*1000;
unique_lock lock(mutex);
condition.timed_wait(lock, sleepTime);
// fetch the current message list
copyList.swap(queue);
}
BOOST_FOREACH(const std::string& s, copyList) {
logfile << s << '\n';
}
logfile.flush();
}
}
};
int main()
{
FileLogger fileLogger("logfile.txt");
fileLogger.Log(std::string(1000*1000, '*'));
// this call should wait, synchronously, until
// current queue has been flushed to disk
fileLogger.WaitForQueueFlush();
}
So the problem is to implement FileLogger::WaitForQueueFlush. How can I
signal the main thread when the queue has been emptied?
Thanks in advance!
Regards,
Daniel Lidström
Stockholm, Sweden
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net