C インターフェイスを備えた C++ ライブラリを開発しています。C インターフェイスには、次のものがあります。
- ライブラリを初期化する関数 (
Init()
— 指定されたパラメータで機能を実装するオブジェクトを構築します); - ライブラリを初期化解除する関数 (
DeInit()
— そのオブジェクトを破壊する)、および; - オブジェクトの対応するメソッドを呼び出すだけのいくつかの関数 (たとえば
Foo()
とBar()
)。
クラス自体はスレッド セーフですが、C インターフェイス ( Init()
、DeInit()
、Foo()
およびBar()
) もスレッド セーフにする必要があります。
単一のグローバル変数、つまりクラス インスタンスへのポインターがあります。次のアプローチのうち、どれが最良だと思いますか? もっと違う方法でやりますか?
unique_ptr<T>
グローバル読み取り/書き込みロックと共にグローバルがあります。Foo()
読み取り用にBar()
ロックします。書き込みのためにロックしますInit()
。DeInit()
- セマフォを使用して、インスタンスを使用しているスレッドの数を追跡します。が呼び出された場合
DeInit()
、セマフォのカウントが 0 になるまで待機します。 shared_ptr
セマンティクスを使用します。グローバルshared_ptr
は変更できますが、ユーザーがなくなるまでオブジェクトは削除されません。Init() は保留中の操作が完了するまで待機しない (そして待機する必要がない) ため、保留中の操作のニーズを満たす (多くのメモリを消費する) いくつかのインスタンスが存在する可能性があるため、システムが過負荷になる可能性があります。 .
オプション 3 は、C++11 を使用して実装するのが最も簡単なようです。私が間違っていたり、曖昧すぎる場合は、私を修正してください。
編集の明確化: Init() および DeInit() への呼び出しはグローバル ポインターを変更しているため、ロックによって同時に実行されないようにする必要があります。Foo() と Bar() は同時に実行できるはずです。
編集の明確化 C インターフェースとは、C インターフェースを実装する関数のセットを意味します。この一連の関数をスレッドセーフにしたい。