ソケット通信クラスを持つ C++ プログラムがあります。各ソケットには、出力メッセージを組み立てるための大きな専用バッファーがあるため、使用法は次のようになります。
class CSocketClass {
public:
SetMsgHeader(int n) { Mutex_.lock(); DoWhateverIsNeededToSetHeaderInBuffer(n); } // where n would be the message type
SetMsgField(double a); { DoWhateverIsNeededToSetDataInBuffer(a); } // where a would be some arbitrary content
SendMsg(); { DoWhateverIsNeededToSendBuffer(); Mutex_.unlock(); } // where this would send the number of bytes added to the buffer since the header was set
private:
char buffer[reallylarge];
MiscSocketApparatus...
boost::mutex Mutex_;
};
複数のスレッドがメッセージを送信しようとしている可能性があります。各スレッドは、ヘッダー、コンテンツを設定し、最後に途中でメッセージを送信する 3 つ以上の呼び出しで構成されています。それらが競合しないようにするために、Mutex を使用して、一度に 1 つのライターのみを維持しようとしました。望ましい動作は、最初に到着したライターがミューテックスのロックを解除するまで、2 番目に到着したライターをブロックすることです。その後、ブロックされたライターは続行できます。
これはほとんどの場合うまくいくようですが、まれに (毎日ではありません)、デッドロックが発生することがあります。
私は、スコープ付きロックを使用した単純なロックの問題に精通していますが、これらの概念は、ロックを所有するオブジェクトへの多数の呼び出しにわたってロックを永続化する必要があるこの問題に完全に変換されない場合があります。
Boost Synchronication チュートリアルを読むと、これを行うためのより良い方法があると思いますが、何が最適かは明確ではありません。
任意の推奨事項をいただければ幸いです。