I face the following situation (which I have to admit I'm too noob to trust myself in solving alone..): I have thread A which occasionally creates new cv::Mat objects for thread B to consume. I need a thread-safe container C (a boost::circular_buffer in this case) which will hold the cv::Mat objects thread A generates. Then, thread B needs to constantly iterate through all items in C to produce an animation. Therefore I need a thread-safe C which will disallow data-races but also cause no (ideally) or very small (if not possible otherwise) lag to thread B's animation -> I dot want thread B to freeze when thread A updates C. The best I could come up with is this:
#include <boost/circular_buffer.hpp>
#include <opencv2/core.hpp>
#include <boost/core/noncopyable.hpp>
#include <memory>
#include <type_traits>
#include <algorithm>
using im_buf = boost::circular_buffer<cv::Mat>;
class ImageBuffer : private boost::noncopyable {
private:
im_buf buffer;
std::mutex mtx;
std::unique_lock<std::mutex> lock;
public:
// operator<< accepting cv::Mat, cv::Mat& and cv::Mat&&
template <class T,
class = typename std::enable_if
<std::is_same<cv::Mat, typename std::decay<T>::type>
::value>::type>
void operator<<(T&& mat) {
lock.lock();
buffer.push_back(std::forward<T>(mat));
lock.unlock();
}
template <typename Func> // excpect callable objects only
inline void iterate(Func func) {
lock.lock();
std::for_each(buffer.begin(),buffer.end(),func);
lock.unlock();
}
inline ImageBuffer():
buffer {settings::max_images_in_loop},
mtx {},
lock {mtx} {}
~ImageBuffer()=default;
ImageBuffer(const ImageBuffer&&)=delete;
ImageBuffer& operator=(const ImageBuffer&&)=delete;
};
(Note that even if this is not an invariant, thread B is not suppose to mutate C or any of its contents (I'd love to use a const_iterator here but boost::circular_buffer does not provide one..)
Yet, with this code thread B will freeze the entire animation for some time each time thread A adds new elements.. so, a. isn't there some better approach?? b. is implementation truly thread safe?
Aucun commentaire:
Enregistrer un commentaire