Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Create Thread-Safe Buffers / POD?

My problem is quite common I suppose, but it drives me crazy:

I have a multi-threaded application with 5 threads. 4 of these threads do their job, like network communication and local file system access, and then all write their output to a data structure of this form:

struct Buffer {
  std::vector<std::string> lines;
  bool has_been_modified;
}

The 5th thread prints these buffer/structures to the screen:

Buffer buf1, buf2, buf3, buf4;

...

if ( buf1.has_been_modified || 
     buf2.has_been_modified || 
     buf3.has_been_modified || 
     buf4.has_been_modified )
{
  redraw_screen_from_buffers();
}

How do I protect the buffers from being overwritten while they are either being read from or written to?

I can't find a proper solution, although I think this has to be a quiet common problem.

Thanks.

like image 632
dummy Avatar asked Apr 25 '15 21:04

dummy


1 Answers

You should use a mutex. The mutex class is std::mutex. With C++11 you can use std::lock_guard<std::mutex> to encapsulate the mutex using RAII. So you would change your Buffer struct to

struct Buffer {
   std::vector<std::string> lines;
   bool has_been_modified;
   std::mutex mutex;
};

and whenever you read or write to the buffer or has_been_modified you would do

std::lock_guard<std::mutex> lockGuard(Buffer.mutex); //Do this for each buffer you want to access
... //Access buffer here

and the mutex will be automatically released by the lock_guard when it is destroyed.

You can read more about mutexes here.

like image 152
phantom Avatar answered Sep 28 '22 18:09

phantom