0

In my application I would like to implement an efficient data logger that would print traces to a file. The application runs on Beaglebone Black and there are some soft time critical spots. That's why I wouldn't like to simply print traces on the go as that would slow down the application. I was wondering about creating a singleton datalogger class that would do this. Now I am wondering about saving traces to string variables that are pushed to a list. Items are then taken from the list in a separate thread and saved to file.

Now the way I know how to do it is to check either the list length is bigger than 0 in that separate thread every couple of ms, ie every 100ms using sleep. The thing is that the more frequently I check, the more processor power is going to be consumed. I know that there are Linux mechanisms like watchers that can watch for a change in a file. I was wondering does such mechanism exists for a variable? For example, I would increment an integer variable each time I put an item to the list, the saving to file thread could then trigger as the watched variable changed.

I'm not even sure either this mechanism is the best approach for the application, its just something I thought of.

halfer
  • 19,824
  • 17
  • 99
  • 186
Łukasz Przeniosło
  • 2,725
  • 5
  • 38
  • 74
  • File I/O is not that bad as the OS does buffering for you. If your application is already multithreaded a synchronised queue is the way to go. You may consider to pull in some logging framework like log4cxx or Boost.log. See some hints here: [C++ logging framework suggestions](http://stackoverflow.com/questions/1736295/c-logging-framework-suggestions) – stefan Jun 22 '15 at 19:29
  • Stefan, thank you for the links. I will keep them in mind for future projects, but for now those frameworks would be bigger than my whole application. I would like to keep it simple and get to learn something new for now, thats why I would like to write the logger myself. – Łukasz Przeniosło Jun 22 '15 at 19:33

1 Answers1

0

There are different solutions to communicate between different threads. Since you are already going to pay for synchronization to the list, you could add a condition variable and use that to notify the other thread:

// sketch
class SynchedQueue {
   std::deque<std::string> data;
   std::mutex              m;
   std::condition_variable cv;
public:
   void push_back(std::string s) {
       std::unique_lock<std::mutex> l(m);
       data.emplace_back(std::move(s));
       cv.notify();
   }
   std::string pop_front() {
       std::unique_lock<std::mutex> l(m);
       cv.wait(l, [&]() { return !data.empty(); });
       std::string r = std::move(data.front());
       data.pop_front();
       return r;
   }
};
David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • So If i have understood everything correct, the push_back method safelly puts a string item into the queue and pop_front is supposed to be placed in the separate thread in while(1)? – Łukasz Przeniosło Jun 22 '15 at 19:30
  • I am trying to follow your example and implement it. I have read some about the `condition_variable::wait()` and it seems like it needs to have an unique_lock passed as first argument, I cant quite understand your line `cv.wait([]() { return !data.empty(); });` could you clarify please? This seemsto work for me, im still writing the code: `m_cv.wait(ul, [this]() { return !m_data.empty(); });` – Łukasz Przeniosło Jun 25 '15 at 08:08
  • @ŁukaszPrzeniosło: I sketched the solution, did not run it through a compiler and it had a couple of issues... but you figured it out – David Rodríguez - dribeas Jun 25 '15 at 13:58