std::vector
はスレッドセーフではありませんでしたので、私はを非常に簡単に構築して、スレッドセーフであるようにカプセル化しました。デストラクタからboost :: mutexをリリースしました
これは非常にうまくいきますが、少し問題があります。 クラスのインスタンスが破棄されていて、別のスレッドが引き続きデータを読み込もうとしているとき、スレッドは永遠にハングし続けます。boost::mutex::scoped_lock lock(m_mutex);
どうすればこの問題を解決できますか?最高ののは、スレッドにぶら下がっているスレッドが実行を継続できるように、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();
}
編集私は私の定義を変更する必要があります。以前に述べたように、コンテナは明らかにスレッドセーフではありません。たとえその命名法が誤解を招くものであっても、そうすることは想定されていません。もちろん、スレッドセーフではないことを行うことができます。しかし、1つのスレッドだけがコンテナに書き込みます.2つまたは3つのスレッドから読み込みます。プロセスを停止しようとするまでうまく動作します。私はモニターが良いと述べなければなりません。しかし、時間がなくなり、私はこれまでこれを変更することはできません。
ご了承ください。ありがとうございました。
私はあなたがより高いレベルでスレッドの問題を抱えていると思います。スレッド1がスレッド2が参照を持っているオブジェクトを破棄するのが正当だと考えることはエラーのようであり、スレッド2から参照できると信じています。スレッド1が実際にオブジェクトを完全に破壊し、スレッド2がそこから読み取ろうとした場合はどうなりますか? –
コピーコンストラクタも* other *ベクタをロックする必要はありませんか? –
コピー代入演算子の実装についても興味があります。劇的に間違ってしまうのは簡単でしょう。 –