メインのスレッドと結合可能な処理スレッドの 2 つのスレッドを持つプログラムで使用するために、独自のロギング クラスを実装することになっています。どちらかのスレッドがロガーを使用しているときに、もう一方のスレッドでロガーを使用したくないので、wxMutex を使用することにしました。ロガーは、operator<< を使用して C++ ostream のように動作する必要がありますが、ストリーム操作関数 (std::endl など) がロガーの出力の終わりを示す点が異なります。ミューテックスがロックされているときに同じスレッドが出力を継続できるように、再帰的なミューテックスが必要だと思います。
問題 (私が思うに) は、ミューテックスが完全にロック解除されていないため、他のスレッドがロガーに出力しようとすると、デッドロックが発生することです。
私のコードに欠けているものはありますか?
class Logger{
private:
std::ostream* out;
wxMutex* mut;
....
public:
template<class T>
Logger& operator<<(T str){ // accept any type of input and lock outputting until finished
if(out){
if(mut->TryLock() == wxMUTEX_BUSY){ // if we didn't get lock
mut->Lock(); // we block
}
if(out){
(*out) << str;
out->flush();
}
//mut->Unlock(); // leave locked until done outputting (use std::endl or similar)
}
return *this;
}
// accept stream manipulators and unlock stream output
Logger& operator<<(std::ostream& (*pf) (std::ostream&)){
if(out){
if(mut->TryLock() == wxMUTEX_BUSY){
mut->Lock();
}
(*out) << pf;
out->flush();
while(mut->Unlock()!= wxMUTEX_UNLOCKED);
}
return *this;
}
};