Mutex#locked? はいらない子?

スレッドやセマフォはカタカナで書いても平気ですが、ミューテックスはカタカナだとすごく気持ち悪いです。あとタプルとかもかなり抵抗があります。なぜだろう。


そんなことはどうでもよくて本題。Mutex#locked? って何のためにあるんでしょうか。簡単な事例を考えてみました。

mutex.unlock if mutex.locked?

このプログラム断片は「mutex がロックされているときだけアンロックする」ように見えますが、よく考えると "if mutex.locked?" の部分に意味はほとんどありません。mutex.locked? が true を返した直後にコンテキストスイッチしたら、返り値が信用できなくなるからです。

if mutex.locked?
  mutex.synchronize { foo }
end

これも「mutex がすぐにロックできるときだけロックして foo を呼ぶ」ように見えますが、同様の問題があります。こういう時は Mutex#try_lock を使うべきです。
locked? が本質的に便利そうな場面は、あまり一般的でない事例しか思いつきませんでした。mutex のロック頻度をポーリングで観測してデバッグやパフォーマンス測定に使うとか、mutex のロック状況によって処理の順序を変えた方が速くなる (つまり最適化に使える) とか。
以上の僕の考えが正しければですが (そんなに自信はない) 、locked? は簡単そうに見えて実は取扱注意なメソッドであると意識・周知すべきだと思います。なんとなく、現状の locked? の存在は「一見動くけど実はレースコンディションになってるバグ持ちコード」を生み出す負の効果が大きい気がしました。まあスレッドなんて要注意だらけですけどね。

追記:続きがあります。

mametter.hatenablog.com