Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread safe implementation of circular buffer

Circular_buffer from boost library is not thread-safe. So I wrapped boost::circular_buffer object in a class as shown below. Mutual exclusion between the threads is achieved (I think) by using conditional variables, a mutex and a lock acquisition/release. Is this implementation thread safe?

#include <boost/thread/condition.hpp> #include <boost/thread/mutex.hpp> #include <boost/thread/thread.hpp> #include <boost/circular_buffer.hpp>  // Thread safe circular buffer  template <typename T> class circ_buffer : private boost::noncopyable { public:     typedef boost::mutex::scoped_lock lock;     circ_buffer() {}     circ_buffer(int n) {cb.set_capacity(n);}     void send (T imdata) {         lock lk(monitor);         cb.push_back(imdata);         buffer_not_empty.notify_one();     }     T receive() {         lock lk(monitor);         while (cb.empty())             buffer_not_empty.wait(lk);         T imdata = cb.front();         cb.pop_front();         return imdata;     }     void clear() {         lock lk(monitor);         cb.clear();     }     int size() {         lock lk(monitor);         return cb.size();     }     void set_capacity(int capacity) {         lock lk(monitor);         cb.set_capacity(capacity);     } private:     boost::condition buffer_not_empty;     boost::mutex monitor;     boost::circular_buffer<T> cb; }; 

Edit This is now a template class, which accepts an object of any type (not just cv::Mat object).

like image 268
Alexey Avatar asked Mar 16 '12 19:03

Alexey


People also ask

Are circular buffers thread-safe?

Thread-Safety This means the circular_buffer is not thread-safe. The thread-safety is guarantied only in the sense that simultaneous accesses to distinct instances of the circular_buffer are safe, and simultaneous read accesses to a shared circular_buffer are safe.

How is a circular buffer implemented?

Circular Buffers can be implemented in two ways, using an array or a linked list. An empty object array along with its capacity is initialized inside the constructor as the type of elements added is unknown. Two pointers namely head and tail are maintained for insertion and deletion of elements.

What is circular buffer used for?

A circular buffer is a utility used to transfer successive data values from a producer thread to a consumer thread, who retrieves the data in FIFO (first in first out) order.


1 Answers

Yes.
If you lock all the public methods with the same lock it will be threadsafe.

You could consider using read-write locks, which may have better performance if you have a lot of concurrent readers.

If you don't have a lot of readers, it will just add overhead, but may be worth checking the option and testing.

like image 114
Yochai Timmer Avatar answered Oct 17 '22 07:10

Yochai Timmer