私には厄介な問題が発生しました。簡単に回避できる状況を見つけたようですが、a) プログラミング中に集中力が途切れた場合、または b) 他の誰かが私のインターフェイスの実装を開始し、処理方法がわからない場合、問題が発生する可能性があります。この状況。
これが私の基本的なセットアップです:
いくつかのデータ型への汎用インターフェイスとして使用している抽象クラスがあります。非仮想パブリック インターフェイス パラダイム (Sutter、2001 年) とスコープ ロックを採用して、ある程度のスレッド セーフを実現しました。インターフェイス クラスの例は次のようになります (スコープ付きロックとミューテックスの実装に関する詳細は、関連性がないと思われるため省略しました)。
class Foo
{
public:
A( )
{
ScopedLock lock( mutex );
aImp( );
}
B( )
{
ScopedLock lock( mutex );
bImp( );
}
protected:
aImp( ) = 0;
bImp( ) = 0;
}
aImp と bImp を実装するのはユーザー次第ですが、ここで問題が発生します。aImp が bImp を使用する何らかの操作を実行する場合、これを行うのは非常に簡単です (ある意味ではほとんど論理的です)。
class Bar
{
protected:
aImp( )
{
...
B( );
...
}
bImp( )
{
...
}
}
デッドロック。もちろん、これに対する簡単な解決策は、パブリック バリアントではなく、保護された仮想関数を常に呼び出すことです (上記のスニペットで B( ) を bImp( ) に置き換えます)。しかし、私がミスを犯したり、さらに悪いことに、他の人が首を吊るすのを許したりした場合、簡単に首を吊るすことはできないようです.
抽象クラスの実装者がコンパイル時にこれらのパブリック関数を呼び出さないようにするか、デッドロックの解決策を回避するのに役立つ方法はありますか?
キックのために、いくつかのミューテックスは、デッドロックの問題を回避する操作を可能にします。例として、Windows 関数の EnterCriticalSection と LeaveCriticalSection を使用してこれを実装すると、問題はありません。しかし、プラットフォーム固有の機能は避けたいと思います。私は現在、スコープ付きロックの実装でboost::mutexとboost::shared_mutexを使用していますが、私が見た限りでは、デッドロックを回避しようとはしていません(私はほとんど好きだと思います)。