std::vector
은 스레드로부터 안전하지 않으므로 스레드 주위를 둘러싼이라는 매우 간단한 캡슐화로 을 만들려고했습니다.boost :: mutex from descructor
이 아주 잘 작동하지만 하나의 작은 문제가있다. 클래스의 인스턴스가 파괴되고 다른 스레드가 여전히 데이터를 읽으려고 할 때 스레드는 계속해서 데이터를 계속 읽습니다. 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 개의 쓰레드는 컨테이너에서 읽는다. 프로세스를 멈추기 전까지는 제대로 작동합니다. 나는 모니터가 더 좋았을 것이라고 말해야한다. 그러나 시간이 없어서 그때까지는 이것을 바꿀 수 없습니다.
어떤 아이디어라도 만족합니다! 고마워, 안부.
높은 수준의 스레딩 문제가 있다고 생각합니다. 쓰레드 1이 쓰레드 2가 참조를 가지고 있고 그것을 읽을 수 있다고 믿는 객체를 파기하는 것이 합법적이라고 생각하는 것은 오류처럼 보입니다. 쓰레드 1이 실제로 객체를 완전히 없애고 _then_ 쓰레드 2가 객체를 읽으려고했다면 어떻게 될까요? –
복사 생성자도 * other * 벡터를 잠글 수 있습니까? –
복사 할당 연산자의 구현을 보는 것도 흥미로울 것입니다. 그것은 그것을 극적으로 잘못 이해하기 쉽습니다. –