[過去ログ] マルチスレッドプログラミング相談室 (986レス)
上下前次1-新
このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
728: 02/10/31 11:06 AAS
APIで上げたスレッドからは一切Cygwinの機能を使わなければ
なんとかなりそうだ
729: 02/10/31 17:33 AAS
pthread仕事で使ってる人います?
730: 02/10/31 17:39 AAS
使うかもしれないから調査中
731: 02/10/31 20:31 AAS
Cygwinのsocketは、未だthread safeではなさげ(DLLのソース読んで確認)
ひとつのfdに対して複数スレッドでaccept(2)して、ひどいめに遭った
732: 02/11/01 02:38 AAS
cygwinってfork使えますか?
733: 02/11/01 02:50 AAS
fork遅いよ
っていうかスレ違いだろ
734(1): 02/11/01 10:45 AAS
cygwinってspoon使えますか?
735: 02/11/02 11:49 AAS
>>734
knifeなら使えます
736(56): 02/11/12 19:32 AAS
Windowsであるクラスに参照カウントを持たせ、InterlockedIncrement./InterlockedDecrementで
マルチスレッド対応にしようとしたのだが…
void ref() {
InterlockedIncrement(&m_ref);
}
void release() {
if (InterlockedDecrement(&m_ref) == 0) {
delete this;
}
}
ところが、delete thisの直後にref()が呼ばれると、m_ref自体が解放された領域にあるため、
とんでもない値になってしまう。参照カウントをメンバー変数にするのが間違い?
どうしたらいんだろう?マルチスレッドのエキスパート様の降臨おながいします
737: 02/11/12 19:55 AAS
> delete thisの直後にref()が呼ばれる
delete thisされたってことは、そのオブジェクトはもう参照されていない
と判断されたんだがら、その後にrefが呼ばれること自体がおかしい。
738: 02/11/12 20:25 AAS
参照カウントを0から始めたに100スレッド
739: 736 02/11/12 21:18 AAS
ある時点で、m_ref>0だったとします。
2つのスレッドが、それぞれ同時にref()とrelease()を呼び出すと…
740: 02/11/12 21:24 AAS
ref() と release() が互いに排他してなきゃ動くわけないじゃん。
741: 736 02/11/12 21:35 AAS
void ref() {
EnterCriticalSection(&m_cs);
InterlockedIncrement(&m_ref);
LeaveCriticalSection(&m_cs);
}
void release() {
EnterCriticalSection(&m_cs);
if (InterlockedDecrement(&m_ref) == 0) {
delete this;
}
LeaveCriticalSection(&m_cs);
}
としても、ref()でInterlockedIncrement()にたどり着いたときには…
742(1): 02/11/12 21:57 AAS
あるオブジェクトに触れるスレッドが一つふえたら
そのオブジェクトの参照カウントをageておく必要があることに
気づいてないに1000はらたいら
743: [ sage ] 02/11/12 21:58 AAS
>739
それもなんだかおかしな動作だな。
refを発行する、というのは、どっかからobjectを貰ってきてるわけだろ。
で、releaseを発行するということは、所有権の一端を持っているわけだよな。
それで、deleteが実行されるというのは、
「refcount == 0かもしれないobjectが渡ってきた」
「release発行しすぎ」
ってなわけだろ。refするタイミングとか、考え直した方がいいんでないか?
744: 736 02/11/12 22:36 AAS
refが参照カウントを増やす(objectを貰って来る)ためのものなのだが…
745(2): 02/11/12 22:52 AAS
736はひょっとしてCOMを知らない?
746(3): 736 02/11/13 10:05 AAS
いやCOMじゃなくて。
あるオブジェクトのインスタンスが作られるとm_ref=1となっていて、
そのオブジェクトを例えば別のスレッドが使うためにコピーを作るとm_ref=2
となる。
まさにその瞬間に、インスタンスの元のホルダーがオブジェクトを破棄しようとすると、
m_refのインクリメントとデクリメントが同時に起きる。
Interlocked...は同時じゃないが、ref()とrelease()が同時に呼ばれrelease()を
実行しているスレッドの方が早くCriticalSectionを獲得して解放したのち、
InterlockedIncrementが呼ばれると、解放されてしまうので値が不定になってしまう。
747: 02/11/13 10:35 AAS
「別のスレッドが使うためにコピーを作る」ときに
「インスタンスの元のホルダーがオブジェクトを破棄」しちゃおかしいだろ。
「別スレッドに渡す」ときにコピーができるもんだろ、ふつー。
748: デフォルトは上限無しさん 02/11/13 10:42 AAS
>>746
Deleteされてしまうことがあるobject自身に、
objectの管理を「全て」任せようということ自体が無理。
Handler patternで行くか、refererにべたにcodeを書いてしまう。
749(1): [ sage ] 02/11/13 10:44 AAS
つーかな。それはrefcountの問題と違うねん。たとえば、
method1() {delete str; str=0; }
method2() {func( *str );}
このメソッド2つが同時実行されるようなのとおなじ問題なわけよ。
あえて解決策を示すなら、
method1() {lock(); delete str; str = 0; unlcok(); }
method2() {lock() if( str ) func(str) unlock(); }
とかしないといけない。
750(3): 02/11/13 11:21 AAS
ひょっとしてrefcountをさらにポインタや参照で管理しようとしてないか?
そんなのrefcountの意味が全くないぞ。根本的にrefcountについて誤解してるだろ。
751: 02/11/13 11:28 AAS
>>750
俺もそんな気がして来た。グローバルなオブジェクトや静的なオブジェクトを
参照カウントでやろうとしてるような気もするし。
752(2): 736 02/11/13 12:37 AAS
>746
やっぱり、そういう事になりますか。
>749
それは、ちっとも解決にならない。
method2がこの場合ref()なわけで、ref()から戻ったら、そのオブジェクト使おうと
するんだから。
>750
参照カウントは、扱われるインスタンス内に有りますが、
そのインスタンスを指すスマートポインターのようなクラスで持たなきゃならないって
事ですか?
そうでなくて、インスタンスと別にアロケートして参照カウント作ってもだめって事だけ?
>グローバルなオブジェクトや静的なオブジェクトを参照カウントでやろうとしてるような気もするし。
流石に、そんなこたぁない。
753(2): [ sage ] 02/11/13 15:40 AAS
分からんヤツやな、、、
refする前にreleaseが発行されてrefcount==0になる
可能性があるなら、refする前に、oobjectが生きてて、
refできるか確かめないかんやろ。その結果、objectが
死んでるなら、refしてobject渡すのは諦めなアカン。
で、そこでobjectが死んでるのが間違いなら、releaseか
refの発行の仕方がオカシイんや。
754(1): 02/11/13 16:49 AAS
>>752
> >746
> やっぱり、そういう事になりますか。
ジサクジエーン?
755(2): 02/11/13 17:03 AAS
>>752
> 参照カウントは、扱われるインスタンス内に有りますが、
> そのインスタンスを指すスマートポインターのようなクラスで持たなきゃならないって
> 事ですか?
> そうでなくて、インスタンスと別にアロケートして参照カウント作ってもだめって事だけ?
場所は関係ない。ただし、インスタンスとカウンタの対応を管理することを考
えれば、インスタンス内に置くか「スマートポインターのようなクラス」って
のが確実で手軽だし常套手段。
参照が増減するたびに必ずカウンタも同期しなきゃ行けないってこと、わかっ
てる? これは本来アトミックな処理なので、別スレッドに渡すってのも参照を
増やすことになるんだけど、それとカウンタの更新を別スレッドに分けちゃい
けない。
単一スレッド内でコピーする場合は複製によるカウント処理が終るより前にオ
リジナルが解放することはないので保護されるけれど、別スレッドにしてしまっ
たらその順序が保証されなくなってしまう。
756: 02/11/13 17:10 AAS
>>754
多分 748 宛てだと思われ。
レス番号と間違えてコメント先頭のポインタを書いてしまう間違いは漏れも時々
やってしまう。
757(1): 736 02/11/13 17:30 AAS
なんか昨日から粘着が居るが
>753
>分からんヤツやな、、、
あんたほどでは(W
>refする前に、oobjectが生きてて、refできるか確かめないかんやろ。
確かめた時生きてても、じゃあ参照しようとしたら死んでる罠
確かめるときに参照かうんと増やす何て言うなよ(W
>755
>参照が増減するたびに必ずカウンタも同期しなきゃ行けないってこと、わかってる?
それは当然ですね。
>これは本来アトミックな処理なので、別スレッドに渡すってのも
別のスレッドに渡すのではなく、
あるスレッドAが参照カウントを持つOのインスタンスをつくって、
別のスレッドBがそのオブジェクトをもらおうとしたらば、
Aはもう要らないとOを破棄しようとしている最中だったわけです。
758(2): 02/11/13 17:38 AAS
>>753
736 にはもう何も言わなくていいよ。
十分答え出てるのに見ようとしないんだから。
759: 02/11/13 17:39 AAS
>>757
> 別のスレッドに渡すのではなく、
「渡す」つってんのはインスタンス自体じゃなくて参照のことをいってんだけど。
ポインタといったほうがいい?
> あるスレッドAが参照カウントを持つOのインスタンスをつくって、
> 別のスレッドBがそのオブジェクトをもらおうとしたらば、
この「もらおうとした」ってどういう状態を考えてるわけよ。
スレッドBはOのインスタンスo1に対する参照を受け取ってないわけ?
もし受け取ってるんならその時点でカウントしないとだめぽ。
760(3): 736 02/11/13 18:22 AAS
>「渡す」つってんのはインスタンス自体じゃなくて参照のことをいってんだけど。
>ポインタといったほうがいい?
「渡す」というのは、あるスレッドAがインスタンスOの参照(カウントが増えた状態)を、別のスレッドB
がアクセスできるようにするという意味で使いました。
そうではなくて、スレッドAの預かり知らぬところで、スレッドBがインスタンスOを
コピー(の過程で参照化運とは増える)して使おうとするということです。
参照を受け取った時には、当然参照カウントは増えていますが、Oの参照カウントを
(クリティカルセクション獲得後)増やそうとしたら、スレッドAが解放してしまっていた
わけです。
>758
そういうなら、参照カウント使ったクラスうpしてみそ。逃げますか?(W
761: 758 02/11/13 18:43 AAS
>>760
逃げる。
そしておまいは困る。ザマーミロ。
762(3): [釣りやろか、、 sage ] 02/11/13 18:47 AAS
>確かめた時生きてても、じゃあ参照しようとしたら死んでる罠
もう一度だけ言うぞ。
「確かめる」と「ref()呼ぶを」、一つのLock内でやれ。
もちろん、releaseの呼び出しにも、おなじLockをかけろ。
それでも、refcountが0になるなら、releaseを呼びすぎているだけ。
763(1): 736 02/11/13 19:03 AAS
そんなに広い範囲でロックかけないで済む方法ってないの?
764: 02/11/13 19:13 AAS
話してる前提が違うんじゃない?
>method1() {lock(); delete str; str = 0; unlcok(); }
が
method1() {lock(); delete this; /*this = 0;XXX*/ unlcok(); }
だから、method2()のifがそもそも出来ないという話
765(1): [ sage ] 02/11/13 19:44 AAS
lock() str->release(); str = NULL; unlock();
766(1): [ sage ] 02/11/13 19:44 AAS
>763
762のlockはそんなに広くないはずだが。
767(1): 02/11/13 21:20 AAS
>>736
参照カウントが 1 のオブジェクトを複数のスレッドから参照してる時点で、
ref を呼び忘れてる。
参照回数0 のオブジェクトに到達することが正しい振る舞いだとしたら、
それは通常の参照じゃなく、弱い参照だ。
768(1): 02/11/13 23:15 AAS
>>736
そもそも、スレッドが生きているかどうか分からないオブジェクトへの
ポインタを受け取ること自体に問題があるような。まさか、
スレッドA:
p = new クラス();
Bに渡す(p);
p->release();
スレッドB:
p = Aから受け取る();
p->ref();
というコードを書いていないだろうな?もしそうなら構造上の問題。
Bから見える場所にpを格納したなら、その分の参照カウントを数えなくては
ならない。それって本質的にはシングルスレッドでも同じことだけど。
769(3): 02/11/13 23:23 AAS
> あるスレッドAが参照カウントを持つOのインスタンスをつくって、
COM知ってさえいれば・・・
770(1): 02/11/13 23:24 AAS
つか、スレッドBに渡されたことをどうやってAは知るんだ?
771: 02/11/13 23:31 AAS
>>770
普通Aがそれを知る必要は無いと思うが?
単にBが自分でディクリメントすればいいだけで。
772(3): 02/11/13 23:58 AAS
なんか皆さん盛り上がってますが…
>>745 >>769に同意。
リファレンスカウントのサンプルを見たければCOMを勉強すればよい。
それと。日本語で一所懸命書かれてもどうにも伝わりにくいようですな。
C言語で(擬似コードでも可)書いた方が意図が伝わると思いますが。
773(1): 02/11/14 00:03 AAS
>>760
> 参照を受け取った時には、当然参照カウントは増えていますが、Oの参照カウントを
> (クリティカルセクション獲得後)増やそうとしたら、スレッドAが解放してしまっていた
> わけです。
そりゃカウントミスってる。AがOを持ってるところでBがOの参照を受け取って
カウントも増やしたんなら、カウントは2以上のはずだ。その状態でAが解放し
てしまうというのはバグ。
774(2): デフォルトは上限無しさん [ふぅ] 02/11/14 01:03 AAS
Guru of the Week!
Reference Counting - Part III (Multithreading!)
外部リンク[htm]:www.gotw.ca
Reference Counting - Part I
外部リンク[htm]:www.gotw.ca
Reference Counting - Part II
外部リンク[htm]:www.gotw.ca
775(2): 02/11/14 01:23 AAS
おまえらスレッド立てすぎです。
776(2): 02/11/14 01:25 AAS
>>775
2chスレ:tech
777: 775 02/11/14 01:38 AAS
>>776、禿同
マルチスレッド掲示板はやればやるほど
スレッドをsageる方向で書込みしたくなるという面白い側面がありますね。
778: 02/11/14 01:48 AAS
この間ようやくプ逝1も sage を覚えたようですが
779(3): 02/11/14 06:43 AAS
VC++の_beginthreadでプログラムを書いてるのですが
親スレッドから子スレッド(以後スレ)を10本同時進行で走らせていて、すべての処理が終った時
子スレの呼び出しの前に変数でフラグを立てておき、そのスレの最後でフラグをONにし、
親スレでそれを確認してからスレを終わるように処理を書いているのですが、
親スレで子スレのフラグを確認している最中に子スレが書き込みすると処理が停止してしまいます。
(デバックしてみるとその付近で停止したりしなかったりする)
このスレのどこかで参照は同時に行ってもかまわないようなレスをみたのですが(記憶が確かなら…)
同時書きこみでない場合(書き込み中を参照)でもだめなのでしょうか?
クリティカルセッション等やらねばダメなのでしょうか?
それともこのような設計が悪いのでしょうか・・
780: 779 02/11/14 06:48 AAS
>>776
>マルチスレッドプログラミングは、やればやるほど
>スレッドを減らす方向に設計したくなるという面白い側面がありますね
私もスレッドにはうんざりですw
まぁ設計が悪いんでしょうが・・・
781: 02/11/14 07:20 AAS
>>779
DQNは使うな
つーか、一冊でも参考書読め
782: 779 02/11/14 07:31 AAS
よーくデバックすると原因が見つかりました。。^^;
長文書いたにもかかわらずすいません・・
後余談ですが、デバック中に子スレッドでconnect、closesocketを何度かやっていると
ある一定回数(かなりの回数)を超えた時、connectが出来ない状態になりました。
何らかのエラーが発生した場合そのエラーを表示するようにプログラムを
書いているのですが全く表示されません。
Socketの処理は居たってシンプルなもので、スレッドとは別で行っているのでバグは無いと思うのですが・・。
このような事は通常起こり得るのでしょうか?
783: 736 02/11/14 10:50 AAS
どうして、参照カウントが増えた後の話にしたがるのか…
784(1): 02/11/14 11:07 AAS
>765
>766
参照カウントを持つオブジェクトのリストがあって、追加・削除、参照(+そのための検索)
を行おうとすると、それぞれでリスト全部ロックしないと…
まあ、注目してるノードとその前後だけロックというのも有りうるけど面倒すぎる。
リスト自体が要素すうもってるし。
>767
参照できるようにする過程での話です。
参照カウントインクリメント不足は、お腹一杯。
>768
スレッドBのAから受け取る()は、どういう処理?
そのなかで、当然Mutexとかで排他制御して参照カウント増やすんでしょ?
その瞬間の話。
>769
実はCOMです。
COMのモジュール内で持ってる情報の管理でつまずいてる。
769はSTAだけつかってなさい。
785(2): 02/11/14 11:11 AAS
AA省
786(2): 736=784=785 02/11/14 11:23 AAS
AA省
787: 736 02/11/14 11:26 AAS
>>773
> そりゃカウントミスってる。AがOを持ってるところでBがOの参照を受け取って
> カウントも増やしたんなら、カウントは2以上のはずだ。その状態でAが解放し
> てしまうというのはバグ。
はぁー。
受け取る処理ってどうやるのさ?
>774
これからよく読んでみます。
ありがと。
788(1): 02/11/14 11:27 AAS
>>786
> Thread A Thread B
ここでBは既にO1への参照を持ってんだろ?
> delete O1呼び出し O2 = O1 (otherがO1)
789(5): 736 02/11/14 11:34 AAS
O1は、スレッド間で共有しているリスト中の要素としてある。
O2=O1は、そのリストから目的の物を検索して取り出す処理の中。
790: 02/11/14 11:35 AAS
マルチスレッドのプログラムで
素朴リファレンスカウントGCをやるなら、
すさまじい細粒度ロックで効率が低下するのは
覚悟しなきゃ。
(普通のGCを使ったほうがずっと速いよ。)
791(1): 02/11/14 11:53 AAS
>>789
やっぱりおかしいな。リストがStringを持ってるわけだろ?
それで、Thread Aがリストから要素を削除したら~String()が呼ばれる
わけだが、その前にThread Bがリストの要素への参照を持ってるなら
参照カウントは2になってなきゃおかしい。
こういうことするなら、当然文字列を指す可能性のあるオブジェクト
全部にリファレンスカウント付けて管理してるんだろ?
792: 02/11/14 11:58 AAS
そうか。Stringというより
GarbageCollectedというスマートポインタを作って、
ヒープのオブジェクト全部GarbageCollectedを継承するように
するんだな。
そして、リストの検索とかやるときは、1つ1つの要素を
ロック・ref++・アンロック、ロック・ref--・アンロックすると。
793(1): 02/11/14 12:21 AAS
>>789
もしかして
「排他制御せずにリストにアクセスしたら、変になるんですけど。」
って言ってる?
スレッドAがリスト中のO1を削除するには、
list.remove(index)
あるいは
list.remove(O1)
スレッドBがO1のコピーを作るには、
O2 = list.get(index)
だよな?
で、この get と remove はロックを使わずやりたいと。
そういうことか?
794: 736 02/11/14 12:31 AAS
>791
>その前にThread Bがリストの要素への参照を持ってるなら
>参照カウントは2になってなきゃおかしい。
リストの要素への参照とは?
O1がそれだと言っているのか(W
>793
>で、この get と remove はロックを使わずやりたいと。
>そういうことか?
そう。
でも、
>「排他制御せずにリストにアクセスしたら、変になるんですけど。」
という事じゃない。
removeで要素中のO1は削除されるけど、Thread BがO2を手に入れていれば
O1-+
+-->ref:2,data:"ABC"
O2-+
から
O2---->ref:1,data:"ABC"
となり、他のスレッドは、もはやこのデータにアクセスできないが、
Thread BはO2から使える。O2が不要になって破棄したら、データ本体も解放される。
795: [ sage ] 02/11/14 12:37 AAS
リスト操作たるgetとremoveにlockかけんかったら、
そいつらが平行したらあぼーんちゃうの。
まあ、「いや、実は〜」とかいって
新状況が出てくるのかも知らんけど(ワラ
796(2): 02/11/14 15:34 AAS
>>755で
> 参照が増減するたびに必ずカウンタも同期しなきゃ行けないってこと、わかっ
> てる? これは本来アトミックな処理なので、
と書いてある意味分かんないのか?
>>789
> O2=O1は、そのリストから目的の物を検索して取り出す処理の中。
てんなら、その処理中での参照の追加とカウントの増加は原理的に(そのオブ
ジェクトに対する)排他処理は必須ってことなんだが。
797(1): 02/11/14 15:42 AAS
「getしてO1の参照先のref countが増える」までが
アトミックに行われないとまずいね。
getが返すべきO1を得た後で、かつO1のrefが増える前にrefがゼロに
なっちゃう。
やはり、
・リスト全体にmultiple-readers-single-writer lockをかける。
・リストの要素1つ1つに排他的ロックをかける。
のどちらかが必須。
798: 02/11/14 15:50 AAS
>>796 禿同
getの中で「注目してるオブジェクト」を示すポインタが
あれば、そいつの参照も数えるべき。
あるオブジェクトを指す変数がある瞬間に3つあるなら
(たとえば「リストから」「Thread Aの局所変数から」
「Thread Bの局所変数から」)、参照カウントはその瞬間
3でないと間違い。
799(1): 02/11/14 20:52 AAS
>>784 (=783?)
>実はCOMです。
>COMのモジュール内で持ってる情報の管理でつまずいてる。
COM扱っててこの有様は信じられない。
800: 736 02/11/14 21:27 AAS
>796
未だに問題のポイントがわかってない言語障害者が居ますね。
>797
やっぱり、そうなっちゃいますかね。
>799
COMは関係なかろう、STAならInterlock何かする必要無いし、
そうでなければ、COMでも同じ。
801: 02/11/14 21:44 AAS
ふつーのGC使えば、誤爆開放しちゃうdangling pointer問題からは
逃れられる。
でも、2人が同時にリストにあぷデートに行ったらどうやっても
ロック必須だけどナー
802: 02/11/14 22:05 AAS
なんか禿しく釣られまくったような気がしてきた…。
803: 02/11/14 22:17 AAS
ところでReadWriteLockでスタベーションフリーでLockのUpgrade/Downgradeも
できるようなの誰か知らんか?
804(1): 02/11/14 22:20 AAS
>>736
考え方おかしいよ。
管理する側とされる側がごっちゃになってる。
そもそもdelete後に破棄されたインスタンスの排他制御
オブジェクトを参照しようとしてる事をおかしいと思わないの?
805(2): 02/11/14 22:28 AAS
便乗で質問です。
スレッド間で、GC(インクリメンタルなマーク&スイープ)で管理された
共有領域のメモリオブジェクトを使いたいんですが、メモリオブジェクト
にはアクセスする度に排他制御しないといけませんよね?
参照するだけなら不要なのはわかるんですが、ポインタを繋ぎ変えたりも
したいので、結局双方でロックしてないと駄目ですよね。
素直に組むと、メモリオブジェクトの粒度が小さいので排他制御にかなり
の時間が割かれてしまいそうなんですが、良い方法はないでしょうか。
素人考えで思いついたのは、スレッド毎にローカルなメモリオブジェクト
領域を使って、処理が完了したら、その結果を共有メモリオブジェクト
領域に移すという方法で、排他制御は共有メモリにアクセスするとき
のみ掛けるというものですが、この方法だとスレッド毎にGCが必要な気が
します。
もっと一般的な方法があったらお願いします。
806(1): 02/11/15 01:09 AAS
>>805
読むだけなら排他制御は不要だよ。
整数や文字を書き込むときも(共有変数以外は)不要。
ポインタを書いたときはライトバリアでGCに通知。
これも別に排他制御はいらない。たとえばスレッドごとにキューを作って、
ページ単位とかでまとめて渡せばよい。
807: 805 02/11/15 03:22 AAS
>>806
ありがとうございます。
ライトバリアでマークする経路を保証するって事ですよね。
共有領域とローカルの区別をする手段が思いつかない(複数
ブロックにまたがってる)んで、改竄個所を全部保護する様に
書き直さないとまずいのかな。
ちょっと考えてみます。
808: 02/11/15 03:25 AAS
ヒープに置くポインタはすべて
template Pointer<class T> ...
みたいなオブジェクトにして、コピーコンストラクタ
でライトバリアをかければよいんじゃないだろうか。
809(1): 736 02/11/15 10:43 AAS
>804
頭おかしいよ。
こんなのどこにでもある。見たこと無いのか?
810: 02/11/15 10:55 AAS
>>736
何人もの人間が否定してるんだから、おかしいのはお前だろ(笑
811(1): 736 02/11/15 11:23 AAS
じゃあ、COMもおかしいのか?
812(3): 02/11/15 11:49 AAS
>>809
「どこにでもある」 が 「おかしくない」 の理由には全然ならない事に気付け。
つーか、そんなのそうそう転がってないはずなんだが、あんたよっぽどクソな
サンプルに見舞われてるんだな。
>>811
おかしいのは COM を把握してないのにわかったつもりになってるあんたの頭。
つーか、教えを乞う立場だったら、もっと謙虚になれ。
主観を捨てろ。
答えへのポインタはもう不必要なほど出ているのに、あんたはそれを全部捨てている。
813(2): 736 02/11/15 12:24 AAS
>812
>つーか、教えを乞う立場だったら、もっと謙虚になれ。
共有しているオブジェクトの集合に丸ごとロックかけずに、
各オブジェクトの参照カウントだけで済むかがポイントなのに、
参照カウントのインクリメント不足だとか、
COMを知ってればとか、
おんなじ事 おんなじ事 おんなじ事 おんなじ事 ばかーーーり。
しつこつ しつこく しつこーーーーく 同じこと繰り返す粘着が多くてウンザリ。
getはアトミックだとか…あのなあ、それ自体はアトミックでもremoveとgetを同時に呼ぶことは出来るんだよ。
参照を持っているならとか…あのなあ、その参照を受け取るのがgetだろ。共有オブジェクトのgetなんだよヴォケ。
じゃあ、参照を手に入れる処理を書いてみろというと、とたんに逃げ出す。
どうしてポイントがずれた香ばしい奴が多いのか。
814: 736 02/11/15 12:26 AAS
>812
>「どこにでもある」 が 「おかしくない」 の理由には全然ならない事に気付け。
>つーか、そんなのそうそう転がってないはずなんだが、あんたよっぽどクソな
>サンプルに見舞われてるんだな。
これ見たこと無いか?
static ULONG WINAPI Increment(LPLONG p) {return InterlockedIncrement(p);}
static ULONG WINAPI Decrement(LPLONG p) {return InterlockedDecrement(p);}
ULONG InternalAddRef() {
return _ThreadModel::Increment(&m_dwRef);
}
ULONG InternalRelease() {
return _ThreadModel::Decrement(&m_dwRef);
}
STDMETHOD_(ULONG, AddRef)() {return InternalAddRef();}
STDMETHOD_(ULONG, Release)() {
ULONG l = InternalRelease();
if (l == 0)
delete this;
return l;
}
まあ、君のコードの中では、
static ULONG WINAPI Increment(LPLONG p) {return ++(*p);}
static ULONG WINAPI Decrement(LPLONG p) {return --(*p);}
しか使われないと思うが(W
815: [ sage ] 02/11/15 12:37 AAS
736の、これまでの発言で推測できること。
1.listでCOM objectを束ねているらしい
2.list内のあるCOM objectに対して、
releaseとrefが(release->refの順で)発生して死ぬようだ
3.list全体に対するlockはかけたくないらしい
(listが持つCOM objectに対する個々のロックは可能みたい?)
736の発言だけで、この問題がわかるかってーの。
それを736の時点で言えば、まだ混乱は少なかっただろうに。
変に情報を出し惜しむから、おなじ事をしつこく何度も
言われる羽目になる。おまけに自分のことを棚に上げて
しつこいとか、ポイントがずれてるとか、香ばしいとか言うし。
816: 736 02/11/15 12:40 AAS
それで?
817: [ sage ] 02/11/15 12:42 AAS
で、815であげた推測は正しいのかい?
というか、コードだせ、コード。問題の起こる、
必要最小限の、736の書いたコードを。
818: 736 02/11/15 12:44 AAS
738 :デフォルトの名無しさん :02/11/12 20:25
参照カウントを0から始めたに100スレッド
740 :デフォルトの名無しさん :02/11/12 21:24
ref() と release() が互いに排他してなきゃ動くわけないじゃん。
742 :デフォルトの名無しさん :02/11/12 21:57
あるオブジェクトに触れるスレッドが一つふえたら
そのオブジェクトの参照カウントをageておく必要があることに
気づいてないに1000はらたいら
743 :デフォルトの名無しさん :02/11/12 21:58
>739
それもなんだかおかしな動作だな。
refを発行する、というのは、どっかからobjectを貰ってきてるわけだろ。
で、releaseを発行するということは、所有権の一端を持っているわけだよな。
それで、deleteが実行されるというのは、
「refcount == 0かもしれないobjectが渡ってきた」
「release発行しすぎ」
ってなわけだろ。refするタイミングとか、考え直した方がいいんでないか?
745 :デフォルトの名無しさん :02/11/12 22:52
736はひょっとしてCOMを知らない?
747 :デフォルトの名無しさん :02/11/13 10:35
「別のスレッドが使うためにコピーを作る」ときに
「インスタンスの元のホルダーがオブジェクトを破棄」しちゃおかしいだろ。
「別スレッドに渡す」ときにコピーができるもんだろ、ふつー。
819: 736 02/11/15 12:44 AAS
750 :デフォルトの名無しさん :02/11/13 11:21
ひょっとしてrefcountをさらにポインタや参照で管理しようとしてないか?
そんなのrefcountの意味が全くないぞ。根本的にrefcountについて誤解してるだろ。
751 :デフォルトの名無しさん :02/11/13 11:28
>>750
俺もそんな気がして来た。グローバルなオブジェクトや静的なオブジェクトを
参照カウントでやろうとしてるような気もするし。
753 :デフォルトの名無しさん :02/11/13 15:40
分からんヤツやな、、、
refする前にreleaseが発行されてrefcount==0になる
可能性があるなら、refする前に、oobjectが生きてて、
refできるか確かめないかんやろ。その結果、objectが
死んでるなら、refしてobject渡すのは諦めなアカン。
で、そこでobjectが死んでるのが間違いなら、releaseか
refの発行の仕方がオカシイんや。
820: 736 02/11/15 12:45 AAS
767 :デフォルトの名無しさん :02/11/13 21:20
>>736
参照カウントが 1 のオブジェクトを複数のスレッドから参照してる時点で、
ref を呼び忘れてる。
参照回数0 のオブジェクトに到達することが正しい振る舞いだとしたら、
それは通常の参照じゃなく、弱い参照だ。
769 :デフォルトの名無しさん :02/11/13 23:23
> あるスレッドAが参照カウントを持つOのインスタンスをつくって、
COM知ってさえいれば・・・
772 :デフォルトの名無しさん :02/11/13 23:58
なんか皆さん盛り上がってますが…
>>745 >>769に同意。
リファレンスカウントのサンプルを見たければCOMを勉強すればよい。
それと。日本語で一所懸命書かれてもどうにも伝わりにくいようですな。
C言語で(擬似コードでも可)書いた方が意図が伝わると思いますが。
773 :デフォルトの名無しさん :02/11/14 00:03
>>760
> 参照を受け取った時には、当然参照カウントは増えていますが、Oの参照カウントを
> (クリティカルセクション獲得後)増やそうとしたら、スレッドAが解放してしまっていた
> わけです。
そりゃカウントミスってる。AがOを持ってるところでBがOの参照を受け取って
カウントも増やしたんなら、カウントは2以上のはずだ。その状態でAが解放し
てしまうというのはバグ。
821: 02/11/15 12:48 AAS
736 荒らしケテーイ
(いや、元々そうだったという説もあるが・・・)
という訳で出て逝ってくれ。
822(1): 736 02/11/15 12:51 AAS
君らのしつこさを確認させてやっただけだよ
823: [ sage ] 02/11/15 12:53 AAS
( ´,_ゝ`)プッ
824: 736 02/11/15 12:58 AAS
結局誰も判らんのか。それならそう言えよ無能者ども。
825: 02/11/15 13:00 AAS
>>822
あのさあ、
しつこいのは お ま え (w
消えろ
826(1): 02/11/15 13:03 AAS
>>813
> 共有しているオブジェクトの集合に丸ごとロックかけずに、
> 各オブジェクトの参照カウントだけで済むかがポイントなのに、
参照カウントのインクリメントにはロックは*原理的に*必要不可欠。
してないのはシングルスレッドを前提にしてる場合だけ。
わかった?
> 参照カウントのインクリメント不足だとか、
> COMを知ってればとか、
> おんなじ事 おんなじ事 おんなじ事 おんなじ事 ばかーーーり。
> しつこつ しつこく しつこーーーーく 同じこと繰り返す粘着が多くてウンザリ。
なんでおんなじ事をこんなにしつこく説明してやらなきゃならんのか…。
> getはアトミックだとか…あのなあ、それ自体はアトミックでもremoveとgetを同時に呼ぶことは出来るんだよ。
> 参照を持っているならとか…あのなあ、その参照を受け取るのがgetだろ。共有オブジェクトのgetなんだよヴォケ。
そのアトミックなgetにカウントのインクリメントを含めてないからバグって
んだろが。
827(1): 736 02/11/15 13:07 AAS
まだ言ってるのか。
>参照カウントのインクリメントにはロックは*原理的に*必要不可欠。
>してないのはシングルスレッドを前提にしてる場合だけ。
>わかった?
void ref() {
EnterCriticalSection(&m_mutex);
InterlockedIncrement(&m_ref);
LeaveCriticalSection(&m_mutex);
}
void release() {
EnterCriticalSection(&m_mutex);
if (InterlockedDecrement(&m_ref) == 0) {
delete this;
}
LeaveCriticalSection(&m_mutex);
}
としたら満足か?(W
828: 736 02/11/15 13:09 AAS
>826
おまえ、InterlockXXってなんのためにあるのか知らんだろ。
知らない奴に限って、無駄なレスを返しやがる。
829: 02/11/15 13:12 AAS
としたら満足か、って・・・
一体何の為にここに質問に来たんだ?
830(1): 02/11/15 13:17 AAS
736の無能っぷりをさらけ出すスレはここですか?
>>837
>EnterCriticalSection(&m_mutex);
> InterlockedIncrement(&m_ref);
>LeaveCriticalSection(&m_mutex);
クリティカルセクション張ってるんだから、
インターロック不要なんだけど。
>EnterCriticalSection(&m_mutex);
> if (InterlockedDecrement(&m_ref) == 0) {
> delete this;
> }
>LeaveCriticalSection(&m_mutex);
自分で書いてておかしいと思わないのかなあ・・
831: 736 02/11/15 13:21 AAS
>>836
あのなあ、
>>参照カウントのインクリメントにはロックは*原理的に*必要不可欠。
>>してないのはシングルスレッドを前提にしてる場合だけ。
>>わかった?
というのは読めないのか。お前は、自然言語にたいする理解力は0だな。
ロックかけなきゃだめだと言ってるやつがいるから、ロックしたまで。
なーんの解決にもならんし、もともと、Interlockしてるから不要なんだがな。
832: 736 02/11/15 13:21 AAS
>830
だわ
833: 736 02/11/15 13:23 AAS
で?826も逃げたのか。全く都合が悪くなると逃げて…自分の発言に席にもてよ。
どうせ、別人のフリしてまた別の事言い出すんだろうが
834: 736 02/11/15 13:26 AAS
ん?deleteまではロックしなきゃダメかな。
まあ、どのみちref()でロック獲得したときに、解放済みというのは避けられんが。
835: 02/11/15 13:28 AAS
>>827
> としたら満足か?(W
で、バグは直ったのか? 漏れが満足したからってバグが消えるわけじゃないぞ。
void Item::ref() {
InterlockedIncrement(&m_ref);
}
Item* List::get() {
EnterCriticalSection(&m_mutex);
Item* p = ...;
p->ref();
LeaveCriticalSection(&m_mutex);
return p;
}
この例で行くとListのget()とremove()で競合が起きるんだろ?
ならListのほうで排他処理をするのが自明の理。
836(1): 736 02/11/15 13:34 AAS
やっぱり、List::get()でリストの検索処理が丸ごとロックするしかないのか。
837(1): 02/11/15 13:40 AAS
(´-`).。oO(100レスかけてようやく染み込んだのか)
838(1): 736 02/11/15 13:49 AAS
それ以外に無いのか聞いてんだが。
ここのいる連中じゃ無理のようだ(W
839(1): 736 02/11/15 13:53 AAS
>812
>「どこにでもある」 が 「おかしくない」 の理由には全然ならない事に気付け。
>つーか、そんなのそうそう転がってないはずなんだが、あんたよっぽどクソな
>サンプルに見舞われてるんだな。
812も逃げたようだな。逃げ足の速い連中だ。
840(1): 02/11/15 14:07 AAS
>>838
> それ以外に無いのか聞いてんだが。
散々いわれてんのに。>>762とか>>785とか。
大体間接的に渡すって話自体>>789くらいでいきなりだし。
>>839
> 812も逃げたようだな。逃げ足の速い連中だ。
いつまでも君の相手してらんないしね。
漏れもそろそろ出かけなきゃならないんでバイバイ。
841: 02/11/15 14:27 AAS
winでのTerminateThreadと同じような
関数はunixにありますか?
842: 02/11/15 14:38 AAS
pthreadならpthread_cancel()かな。TerminateThreadと違って必ずしも即座に
終了するわけじゃないけど。
843: 02/11/15 14:44 AAS
教えて下さい。
pthread_cancel()を実行すると
実行されたスレッドの終了はいつになるのですか?
844: 02/11/15 14:47 AAS
実行してみればわかる
845: 736 02/11/15 15:06 AAS
>840
またバカが湧いてきた。
>散々いわれてんのに。>>762とか>>785とか。
>762は、各オブジェクト毎にロック掛けるって意味ならロックが多量に必要だし、リストにはロック掛けないのか?
リストにロックかけるんだったら、各オブジェクト毎に掛ける必要なし。
君のような厨には理解で菌だろうがな。
>大体間接的に渡すって話自体>>789くらいでいきなりだし。
間接的?ハァ?頭大丈夫?
785は俺だ。
たくっ。ろくに読まないでレスするアホウは書くなっつの。
>いつまでも君の相手してらんないしね。
>漏れもそろそろ出かけなきゃならないんでバイバイ。
いや、君みたいなアホウに相手してくれとは言ってないから(W
お呼びでないの(Wつか出てくんなっての
大体、レスして何か言われたら自分が誰かわかるように名前に番号入れるもんだろ。
言いっぱなしで自己満足してる厨が多すぎ。
846: 736 02/11/15 15:16 AAS
740 :デフォルトの名無しさん :02/11/12 21:24
ref() と release() が互いに排他してなきゃ動くわけないじゃん。
826 :デフォルトの名無しさん :02/11/15 13:03
>>813
> 共有しているオブジェクトの集合に丸ごとロックかけずに、
> 各オブジェクトの参照カウントだけで済むかがポイントなのに、
参照カウントのインクリメントにはロックは*原理的に*必要不可欠。
してないのはシングルスレッドを前提にしてる場合だけ。
わかった?
こういう連中は、
void ref() {
EnterCriticalSection(&m_cs);
++m_ref;
LeaveCriticalSection(&m_cs);
}
void release() {
EnterCriticalSection(&m_cs);
if (--m_ref) == 0) {
delete this;
}
LeaveCriticalSection(&m_cs);
}
って書いてるのかな。馬鹿だなー。
こんな事言ってる奴が多いのは オ ド ロ キ。
もはや都市伝説だな。
847: 736 02/11/15 15:17 AAS
おっ!
830が、慌ててネットで調べ始めた。まあ、自分の馬鹿さ加減を思い知れ。
848: 736 02/11/15 15:21 AAS
おっ!
他にもInterlockだけじゃダメだと思ってる奴も多いな。
まあ、release()のLeaveCriticalSectionがdelete以降なのは論外だが、
void ref() {
InterlockedIncrement(&m_ref);
}
void release() {
if (InterlockedDecrement(&m_ref) == 0) {
delete this;
}
}
じゃだめだと思ってるやつは何か言ってみろ。
どうせ逃げんだろうけどな。
849(1): 02/11/15 15:34 AAS
void ref() {
InterlockedIncrement(&m_ref); // A
}
void release() {
if (InterlockedDecrement(&m_ref) == 0) {
// B
delete this;
}
}
B のタイミングで A が呼ばれた場合。
850(1): 02/11/15 15:45 AAS
void ref() {
InterlockedIncrement(&m_ref); // A
}
void release() {
if (InterlockedDecrement(&m_ref) == 0) {
delete this;
// C
}
}
C のタイミングで A が呼ばれた場合。
しかし、危険性において 846 のコードは結局 848 と変わらないな。
851: 736 02/11/15 15:48 AAS
おいおい、本当にのこのこ出てきたよ。恥ずかしい奴だ。
852: 736 02/11/15 15:50 AAS
>しかし、危険性において 846 のコードは結局 848 と変わらないな。
説明してみろよ。わくわく。
Bのところに行くのは、どういう場合さ?
853: 02/11/15 16:01 AAS
>849
馬鹿です。
854: 02/11/15 16:01 AAS
晒しage
上下前次1-新書関写板覧索設栞歴
あと 132 レスあります
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル
ぬこの手 ぬこTOP 0.038s