排他の仕方
昨日書いた疑似コードだとwrlock中にreadに来たスレッドが全てlock(&m)で待機するため、循環検出の終了待ちスレッドが多いとスループットが一時的に悪化する。これを改善するためにはmutexが獲得出来なかった場合にただ待機するのではなく、再度rdlockしようと挑戦した方が良いだろう。
#define NOLOCK 0 #define RDLOCK 1 #define MLOCK 2 #define SLEEP 100 void read() { int lock = NOLOCK; while (lock==NOLOCK) { if (!tryrdlock(&rw)) { lock = RDLOCK; break; } else if (!trylock(&m)) { lock = MLOCK; break; } else { usleep(SLEEP); } } //排他でのread作業 switch (lock) { case RDLOCK: unlock(&rw); break; case MLOCK: unlock(&m); break; default: //エラー処理 break; } }
だんだん、不格好になってきたなぁ。もっと賢いやり方があるのではないか。少なくともscoped_lockなクラスにした方が良い気がする。