Поскольку std::vector
не является потокобезопасным, я пытался построить вокруг него очень простую инкапсуляцию, которая делает его поточно-ориентированным.
Это работает довольно хорошо, ноесть одна маленькая проблемаКогда экземпляр класса уничтожается, а другой поток все еще пытается прочитать данные из него, поток продолжает зависать навсегда в boost::mutex::scoped_lock lock(m_mutex);
Как я могу решить эту проблему?Лучше всего просто разблокировать мьютекс, чтобы поток, висящий в нем, мог продолжать выполняться.Я не определил деструктор, потому что до сих пор он не требовался.
Вот мой код.Обратите внимание, что здесь больше методов, чем показано здесь, это упрощено.
template<class T>
class SafeVector
{
public:
SafeVector();
SafeVector(const SafeVector<T>& other);
unsigned int size() const;
bool empty() const;
void clear();
T& operator[] (const unsigned int& n);
T& front();
T& back();
void push_back(const T& val);
T pop_back();
void erase(int i);
typename std::vector<T>::const_iterator begin() const;
typename std::vector<T>::const_iterator end() const;
const SafeVector<T>& operator= (const SafeVector<T>& other);
protected:
mutable boost::mutex m_mutex;
std::vector<T> m_vector;
};
template<class T>
SafeVector<T>::SafeVector()
{
}
template<class T>
SafeVector<T>::SafeVector(const SafeVector<T>& other)
{
this->m_vector = other.m_vector;
}
template<class T>
unsigned int SafeVector<T>::size() const
{
boost::mutex::scoped_lock lock(m_mutex);
return this->m_vector.size();
}
template<class T>
bool SafeVector<T>::empty() const
{
boost::mutex::scoped_lock lock(m_mutex);
return this->m_vector.empty();
}
template<class T>
void SafeVector<T>::clear()
{
boost::mutex::scoped_lock lock(m_mutex);
return this->m_vector.clear();
}
template<class T>
T& SafeVector<T>::operator[] (const unsigned int& n)
{
boost::mutex::scoped_lock lock(m_mutex);
return (this->m_vector)[n];
}
template<class T>
T& SafeVector<T>::front()
{
boost::mutex::scoped_lock lock(m_mutex);
return this->m_vector.front();
}
template<class T>
T& SafeVector<T>::back()
{
boost::mutex::scoped_lock lock(m_mutex);
return this->m_vector.back();
}
template<class T>
void SafeVector<T>::push_back(const T& val)
{
boost::mutex::scoped_lock lock(m_mutex);
return this->m_vector.push_back(val);
}
template<class T>
T SafeVector<T>::pop_back()
{
boost::mutex::scoped_lock lock(m_mutex);
T back = m_vector.back();
m_vector.pop_back();
return back;
}
template<class T>
void SafeVector<T>::erase(int i)
{
boost::mutex::scoped_lock lock(m_mutex);
this->m_vector.erase(m_vector.begin() + i);
}
template<class T>
typename std::vector<T>::const_iterator SafeVector<T>::begin() const
{
return m_vector.begin();
}
template<class T>
typename std::vector<T>::const_iterator SafeVector<T>::end() const
{
return m_vector.end();
}
Редактировать Мне нужно изменить свое определение.Контейнер явно не является поточно-ориентированным, как указано выше.Это не должно быть сделано - даже если номенклатура вводит в заблуждение.Конечно, вы можете делать с ним вещи, которые не являются потокобезопасными вообще!Но только один поток пишет в контейнер, 2 или 3 читают из него.Это работает хорошо, пока я не попытаюсь остановить процесс.Я должен заявить, что монитор был бы лучше.Но время уходит, и я не могу изменить это до тех пор.
Любая идея приветствуется!Спасибо и всего наилучшего.