Linuxコンポーネントパッケージ(四)RAII技術を用いてMutexLock自動化ロック解除を実現
2106 ワード
私たちはこのコードを一度も書いたことがありません.
明らかに、このコードではロックを解除するのを忘れています.このような状況をどのように防止するかは、スマートポインタと同じ戦略を採用し、ロックとロック解除のプロセスを1つのオブジェクトにカプセル化します.
[オブジェクトライフサイクル](Object Lifespan)が[ロック期間](Lock Period)に等しいことを確認します.
コードは次のとおりです.
このようなリソース取得をコンストラクション関数、リソース解放をコンストラクション関数に入れる方法は、C++のRAI技術であり、「リソース取得は初期化」である.C++のスタックオブジェクトを巧みに解析するので、リソースは必ず解放されます.
このクラスは私たちが優雅なコードを書くのに、メリットは明らかです.例えば、
このコードは本当に美しいとは言えませんが、MutexLockGuardがあれば、私たちは書くことができます.
コードの美観性が大幅に向上した.
もちろん、次のような使い方が間違っています.
このコードのロック期間はその行に限られています.誤った使用を防ぐために、マクロを追加します.
これにより、エラーが使用されると、コンパイルエラーが発生し、問題が早期に発見されます.
{
mutex_.lock();
//XXX
if(....)
return;
//XXX
mutex_.unlock();
}
明らかに、このコードではロックを解除するのを忘れています.このような状況をどのように防止するかは、スマートポインタと同じ戦略を採用し、ロックとロック解除のプロセスを1つのオブジェクトにカプセル化します.
[オブジェクトライフサイクル](Object Lifespan)が[ロック期間](Lock Period)に等しいことを確認します.
コードは次のとおりです.
class MutexLockGuard : NonCopyable
{
public:
MutexLockGuard(MutexLock &mutex) :mutex_(mutex)
{ mutex_.lock(); }
~MutexLockGuard()
{ mutex_.unlock(); }
private:
MutexLock &mutex_;
};
このようなリソース取得をコンストラクション関数、リソース解放をコンストラクション関数に入れる方法は、C++のRAI技術であり、「リソース取得は初期化」である.C++のスタックオブジェクトを巧みに解析するので、リソースは必ず解放されます.
このクラスは私たちが優雅なコードを書くのに、メリットは明らかです.例えば、
size_t Buffer::size() const
{
mutex_.lock();
int ret = queue_.size();
mutex_.unlock();
return queue_.size();
}
このコードは本当に美しいとは言えませんが、MutexLockGuardがあれば、私たちは書くことができます.
size_t Buffer::size() const
{
MutexLockGuard lock(mutex_);
return queue_.size();
}
コードの美観性が大幅に向上した.
もちろん、次のような使い方が間違っています.
size_t Buffer::size() const
{
MutexLockGuard(mutex_);
return queue_.size();
}
このコードのロック期間はその行に限られています.誤った使用を防ぐために、マクロを追加します.
#define MutexLockGuard(m) "Error MutexLockGuard"
これにより、エラーが使用されると、コンパイルエラーが発生し、問題が早期に発見されます.