From: Yusuke ENDOH Date: 2011-01-26T01:19:08+09:00 Subject: [ruby-dev:43110] Re: pthread_cond を用いたConditionVariable 遠藤です。 2011年1月26日0:32 KOSAKI Motohiro : >>> ええと、いままではGVL持ってるときは他のロックとるの禁止にしてますよね。 >>> GVLスレッドが待ってしまうと、全部止まるから。 >> >> mutex->lock とかは GVL 持ってる時にロックしてますが、そういう話 >> ではない? > > 痛いところつかれた。あれ不思議なんだよなぁ。lock_func()はGVLはずしてから > 読んでるけど、rb_check_deadlock()はGVLを持ちながらmutex->lockをとるという > 不思議なつくりが このへんも試行錯誤の賜物ですね。 >> 私が Ruby を好きな理由は、Kernel#p を始め、デバッグが軽快で楽しく >> なるようにしているところなので、この程度のことで kill -9 が必要に >> なるのは嫌です。 > > それに対する答えは1つしかなくて、CVなんか使うな。ですよ。 > そういう中断できないAPIを選んでるんだから。 > 気持ちよくCtrl+Cで中断したい人はpipe でスレッド間通信しておけばよかったわけです。 どうせ Ruby は今 CV 以外にも全面的に Ctrl+C に脆弱な状況なのに、なんで CV だけ利便性 (1.9.x も変えようというなら互換性も) を捨てて Ctrl+C 対策 しないといかんのかが、どうも腑に落ちない感じです。 > どうしてもCVが使いたければ、プログラムの最初でスレッドつくってmainスレッドはthread.joinするだけ > にしとけば、絶対割り込み可能です。これは十分現実的でしょう。 プロセス終了時に全スレッドに例外 (のようなもの) を投げて join するはず なので、おそらく無意味です。 >> こんな感じですかねえ。 >> >> class SynchronizedQueue >> def initialize >> @array = [] >> @cv = ConditionVariable.new { !@array.empty? } >> end >> def push(x) >> @cv.signal_and_synchronize { @array << x } >> end >> def pop >> @cv.wait_and_synchronize { @array.unshift } >> end >> end > > cv.wait 以外はspurious wakeup問題がないので、特に拡張は不要という > 認識でした。これは構文の一貫性のためだと思って良いのでしょうか? > 見逃しがあったら教えてください。 必須ではないですが、こういう API にしたほうが「cv と mutex をペアとして 扱うこと」や「cv と predicate をペアとして扱うこと」を強制できるので、 そのあたりの誤用も減らせるのではないかと。 ただ、それによって表現力が落ちている可能性はあるのと、もはや Condition Variable ではないなどのツッコミはありえます。 >> そもそも、注意点を網羅的かつ明確に理解できている人が現時点で存在 >> しないという説。 > > 遠藤さん理解してはるじゃないですか・・・・・ 他人の間違いは探せても、体系的に説明できるほど整理できないんですよねえ。 -- Yusuke Endoh