このまえC++だとGCがないのでlock-freeのアルゴリズムを使ってもおいしくないというお話があったと思いますが、GCがlock-freeじゃないということなら実はどっちもどっち? RT @kumagi: @repeatedly lock-freeGCとか垂涎過ぎる…!
2010-11-12 00:23:18@koie んー…C++だとGCが無いのですが、がんばって参照カウンタ使えば実現可能ではあります、でもそれぐらいならロックするGCを使った方がイタレーションにatomicカウンタ回さなくていいぶん遥かに速いんです。イタレーションに処理時間の97%とか食われるとそりゃもう…。
2010-11-12 00:56:04@repeatedly イタレーション中に指してる真っ只中のオブジェクトが運悪くdeleteされるんです。んで、delete済みのアドレスから次のイタレーション用のポインタを読み出そうとした瞬間にsegmentation fault。回避するには削除を遅延させるしかない…。
2010-11-12 01:01:42@kumagi あーなるほど.iteratorとして取り出した段階では生きてても,iterator自体は参照カウントに影響を及ぼさないから,回してる途中に消えちゃうことがあるのね.
2010-11-12 01:05:26@repeatedly ですです。回避するにはiteratorが指してる間には消さない工夫が必要で、カウンタ回す・hazard_ptr使う・GCに任せる のどれかが知ってる解の全てです。他の選択肢常時募集中!
2010-11-12 01:07:56.@kumagi @repeatedly 現在コンテナにアクセスする可能性がある全てのイテレータへのポインタをコンテナが持っていれば、要素の削除を要求されてから全てのイテレータが有効な値を指すように調整し終わるまでの間イテレータをロックすることが出来るかも?
2010-11-12 01:17:41@repeatedly 有効な要素を指していないイテレータは必ずコンテナから生成されているか、それのコピーなので、boost::signalでロックアンロックを通知出来るようにしておいてイテレータの破棄でそのイテレータへの接続が切れるようにしておけばなんとかなるかなと
2010-11-12 01:28:23@fadis_ それがhazard_ptrの考え方ですね。スレッドごとに「今消されたら困るポインタ」を登録しておいて、削除する時に他のどのスレッドも参照していないことを確認するわけです。スレッドごとに一意な数字を指定しなきゃいけなかったりと既存の実装は悩ましいです。
2010-11-12 01:29:19反復処理中ってのはコンテナによって所有されてる状態だから基本的にdeleteされるはずはない、と思うんだけど…。詳しくないから黙っておこう。 RT @kumagi: @repeatedly イタレーション中に指してる真っ只中のオブジェクトが運悪くdeleteされるんです。(以下略
2010-11-12 01:06:10@SubaruG 複数スレッドで寄ってたかって1つのコンテナに削除とイタレーションを繰り返してる場合なので何も配慮しなければ余裕でdeleteは為されます。
2010-11-12 01:11:45他のスレッドに削除されてイテレータ無効にならないの、と思ったけど、リンクリストなら普通に大丈夫なのか。まぁリンクリストすきじゃないけど個人的には。
2010-11-12 01:16:27っていうか参照カウントの問題じゃなくて、要素が削除されることでイテレータが無効になることが本質にあるんじゃないだろうか。とか。
2010-11-12 01:19:00list の iterator でも、今まさに差してるオブジェクトが erase されたら普通に無効になるので。
2010-11-12 01:20:22