トップページ⇒tech
984コメント312KB

マルチスレッドプログラミング相談室 その3

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさんNGNG
マルチスレッドプログラミングについて語るスレ。
OS・言語・環境は問わないが、それゆえ明記すべし。

その1 http://pc3.2ch.net/test/read.cgi/tech/997345868/
その2 http://pc5.2ch.net/test/read.cgi/tech/1037636153/
0153デフォルトの名無しさんNGNG
Delphi付属のサンプルコードに、スレッドを複数立ち上げてソートするコードなかったか?
0154150NGNG
すんません、6Personalなんですが、サンプルコードついてないっぽいです...
0155デフォルトの名無しさんNGNG
scheme(scm)でスレッドを実装したいときはどうすればいいのですか?
make-engineがそれにあたるのでしょうか…
0156デフォルトの名無しさんNGNG
>>152
グローバル変数と一緒。
0157デフォルトの名無しさんNGNG
>>156
回答ありがとう。
しかし...グローバルと一緒ですか...
Priveteならたぶんスレッド内で独立した変数になるんだろうけど、メインのフォーム
から操作する必要あるんですよねえ。
publicな手続きつくってその中でaを操作すればいいのかな。
0158デフォルトの名無しさんNGNG
>>157
御免、言っている意味がよくわからない。
スレッドローカルな変数で、グローバル変数とローカルな変数の中間。
生存期間: そのスレッドが終了すると(TThreadが消えると)なくなります。
アクセス: パブリックなので、アドレス分かればどこからでもアクセス可能。
0159デフォルトの名無しさんNGNG
で、スレッド毎に確保。
そのスレッドから見ればグローバル変数と一緒。
0160157NGNG
なるほど、スレッドローカルな変数ですね。説明ありがとう。
僕も最初そうかと思ったんですけど、実際に動かして見るとどうも動きがちがうのよねえ。

152であげた例でいうと、メインフォームのほうでこいつのインスタンスを二つ作って

Thread1:=TMyThread.Create(False);
Thread2:=TMyThread.Create(False);

でaを操作する。

Thread1.a:=1;

TMyThreadのExecuteでaを監視してるんですが、これやると、なぜかThread2も
反応してしまうんですよ...

どこが間違ってるんでしょうか。ご指導お願い致します
0161デフォルトの名無しさんNGNG
TMyThread のインスタンスはメインスレッドでつくられるんだから、単なるフィールド変数だろ
0162デフォルトの名無しさんNGNG
これデルファイ?C++ならメモリアドレス見れば一発なのに
0163デフォルトの名無しさんNGNG
>>160
スレッドローカルだからでは?
もう自分でも何をしたいのか、よくわかっていないでしょ?
0164157NGNG
皆さんコメント感謝
163さん言うとおり、相当煮詰まってあれこれ試しているうちに
何がなんだか混乱していたのも事実です。

aをpriveteに移して、aをメインスレッド側からいじらないように改造
したら誤動作なくなりました。
正直言うとまだ明確にはわかっていません。

あまりプログラミングの知識ないのですが、最初ごく単純なツール
の予定だったので私でもできるかなと引き受けたのですが、あれよ
あれよと機能追加要求が来て大変です。
でもまあ、あれこれ迷いながら楽しんで仕事できてます。

とりあえず変数の種類とスコープを復習しなおすことにします。
ありがとう。
0165デフォルトの名無しさんNGNG
超高速で操作するとなんかスタックが壊れる・・・
「無効なアンワインド対象がアンワインド操作で検出されました。。」
ってなんやねんわけわかめ!わけわか!
0166デフォルトの名無しさんNGNG
スタック壊れてるのはたいてい自分でメモリを壊してるせい
0167デフォルトの名無しさんNGNG
>>165
「アンワインド」の意味は分かっているの?

スタック上のアンワインド用のメタデータが壊れているんでしょう。
それが餡ワイン度している時に見つかったと。
0168デフォルトの名無しさんNGNG
うへぇ、不味そう<餡ワイン
0169デフォルトの名無しさん05/01/19 13:16:21
クリティカルセクションオブジェクトのLockCountが-1でOwningThreadもNULLで
どこもロックしてないのにLockSemaphoreだけロックされててわけわかめ。なんじゃこれ
もう疲れた
0170デフォルトの名無しさん05/01/23 22:50:00
スレッドの生成や消滅って、implicitなmemory barrierになると考えて良いのでしょうか?
#POSIX, Win32両方使ってます。
0171デフォルトの名無しさん05/01/24 13:58:45
状況がつかめん。
コードで示せ。
017217005/01/24 14:58:01
メインスレッドが大域変数gFooに1を、排他制御なしで書く
↓
メインスレッドがスレッドTを生成する
↓
TがgFooの値を排他制御なしで読む

の順で処理が発生したとき、Tが観測するgFooの値が1であることが保証されているかが知りたいです。
メインスレッドは1を書いた後、当面gFooにアクセスしないと仮定してOKです。

よろしくおながいします。

0173デフォルトの名無しさん05/01/24 16:33:36
>>172
環境によっては保証されない。
何故ならば、大域変数へのアクセス完了を待ってスレッド生成する保証がないから。
017417005/01/24 18:28:24
>>173
> 環境によっては保証されない。
> 何故ならば、大域変数へのアクセス完了を待ってスレッド生成する保証がないから。

gFoo = 1;
// ここ
pthread_create();

というコードで、「ここ」と書いたところはsequence pointで、かつ「ここ」ではまだシングルスレッド
状態なわけですが、それでも「大域変数へのアクセス完了を待つ」が保証されないのでしょうか?

>> スレッドの生成や消滅って、implicitなmemory barrierになると考えて良いのでしょうか?
という質問に戻ってしまうわけですが・・。
0175デフォルトの名無しさん05/01/24 18:52:29
そのコードなら確実に1は保証されるぞ。
1の代入が完了しなければスレッドが作られないんだから。
1の代入とスレッド作成は同一スレッドで行われるわけだからね。
0176デフォルトの名無しさん05/01/24 18:56:38
>>175
前スレの最後の方とか http://www.nwcpp.org/Downloads/2004/DCLP_notes.pdf を見た上でもそう思う?

0177デフォルトの名無しさん05/01/24 19:09:38
アセンブラのレベルで、同一スレッドでmov命令(1代入)発行した後に関数コール(pthread_create)
する場合でも、movが完了する前にpthread_createされることって有り得るの?
そういう話ではないよね?コンパイラのオプティマイザによって変わってくるということかね?
0178デフォルトの名無しさん05/01/24 19:11:43
Pentium4とかの最近のCPUだと有り得る
0179デフォルトの名無しさん05/01/24 19:13:19
コンパイラのオプティマイズ(命令のreorder)の話もあるけど、それに加えて、
・コンパイラがreorderしなくても、CPU(H/W)が命令をreorderするかもしれない
・あるCPUでmovが完了したからといって、その値が別のCPUから観測可能かはわからない
ということでは?
0180デフォルトの名無しさん05/01/24 19:20:28
どうも。勉強不足でした。恥ずかしい。
前スレッドを見たいが見られない。困った。
0181デフォルトの名無しさん05/01/24 19:23:32
>>180
memory barrierでググればそれ関係の論議は大抵見つけられると思う。
018217005/01/24 19:33:12
pthread_createやCreateThreadの先頭にmemory barrier(full fence)が挿入され
ているのか、挿入するよう規格が要請しているかが知りたいです。

#またはfenceなどなくても大丈夫というならその理由を
0183デフォルトの名無しさん05/01/24 20:19:01
volatile
0184デフォルトの名無しさん05/01/24 20:22:17
またvolatile厨か・・・
0185デフォルトの名無しさん05/01/24 21:19:14
total store order
0186デフォルトの名無しさん05/01/24 21:22:38
またtotal store order厨か・・・
0187デフォルトの名無しさん05/01/24 21:24:35
>>185
詳しく
>>186
ポカーン
0188デフォルトの名無しさん05/01/24 21:24:42
どうでもいいじゃん
0189デフォルトの名無しさん05/01/24 21:25:48
スレッドセーフなライブラリつかっとけばOK
019017005/01/24 21:39:43
>>185
> total store order
すみません、memory modeに疎く、TSOだけだとちょっと意図が汲めません。結局>>172の例は
safe/unsafeどちらだとお考えでしょうか?



019117005/01/24 21:40:28
mode -> model
0192デフォルトの名無しさん05/01/24 21:54:32
>>170
volatile とか VC/VC++ の _ReadWriteBarrier とかその辺の問題はともかく、
MSのサンプルでも、Win32のThreadProcで、渡されたデータ、実体はポインタ、
が挿すメモリアクセスするような場合にMemoryBarrier()呼び出しをしている例は
一度も見たことなく、逆の例は沢山あるので、
Win32のCreateThreadはメモリバリアになってるような気がします。

具体的なドキュメント等の記述は見つからないけど。
0193デフォルトの名無しさん05/01/24 21:55:20
↑
編集していたらなんか「、」が多くて変な文になってしまった。
0194デフォルトの名無しさん05/01/24 22:04:25
この名前空間、クラス、およびメンバは、.NET Framework Version 1.1 だけでサポートされています。
0195デフォルトの名無しさん05/01/25 00:30:21
>>170
POSIXではpthread_create()もpthread_join()もMemory Synchronizationが
要請されてますな。
ttp://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html#tag_04_10
019617005/01/25 12:12:35
>>192, 195
ありがとうございます!!
スッキリ解決です。

0197デフォルトの名無しさん05/01/25 22:20:49
このスレでvolatileって言葉が出てきたらほぼ100%厨房な間違いってことでFA。


0198デフォルトの名無しさん05/01/25 23:09:05
つまり
>>56, >>183, >>184, >>192, >>197
はほぼ100%厨房な間違いってことでFA。
0199デフォルトの名無しさん05/01/25 23:09:07
volatileはthreadじゃなくてinterruptのときのモノだしな。
0200デフォルトの名無しさん05/01/25 23:34:26
またvolatile厨か・・・
0201デフォルトの名無しさん05/01/26 00:34:16
>199
ISO C/C++的にはシグナルハンドラからアトミックに更新したい変数に用いる型、だね。
volatile sig_atomic_t。この使い方以外でvolatileって語は出てこないし。

あーあと、POSIXにはまったく登場しないね。
0202デフォルトの名無しさん05/01/26 00:36:59
>>198
56はリア厨だったりする罠。

>通常、小さい変数などはvolatileをつけるべきだってのは知っているのですが、
必要ありません。

>const_castでvolatileを変える仕様はMS VC7.1には入っていないし、
>同期をかけるクラスはすべてvolatile版も作れということですかねぇ。
CRITICAL_SECTION使え
0203デフォルトの名無しさん05/01/26 14:01:57
またvolatile厨か・・・
0204デフォルトの名無しさん05/01/26 15:27:42
またvolatile厨か・・・
0205デフォルトの名無しさん05/01/26 17:22:23
またvolatile厨か・・・
0206デフォルトの名無しさん05/01/26 19:04:35
またvolatile厨ですね・・・
0207デフォルトの名無しさん05/01/26 19:13:18
(またvolatile厨)厨ですよ・・・
0208デフォルトの名無しさん05/01/26 19:14:25
((またvolatile厨)厨)厨ですよ・・・
0209デフォルトの名無しさん05/01/26 19:58:21
こんな(((volatile厨)厨)厨)厨見たことない・・・
0210デフォルトの名無しさん05/01/26 20:36:31
こんなところで三段落ちを見るとは…さすがvolatile厨だな
0211デフォルトの名無しさん05/01/27 00:31:20
来たれ、void厨!
0212デフォルトの名無しさん05/01/28 00:28:17
ということにしたいのですね。
0213デフォルトの名無しさん05/01/28 02:46:28
取り込み中済まないんだけど、mutex で待たないで条件変数で待たなきゃいけない場合って
どんな時ですか? 長い時間掛かる処理を待ってる時は、条件変数使った方が良いみたいですが。

ググったら見つかったとこ。

ttp://www.imou.to/~AoiMoe/column/pthread/pthread_cancel.html

これは、絶対に mutex で待っちゃダメって事じゃないですよね。
0214デフォルトの名無しさん05/01/28 03:08:46
>>213
condition variableで待つ場合ロックしているmutexを一時的に
解放してくれて、かつ、signalやbroadcastで条件が調った時に
一時的に解放していたmutexを自動的にロックしてくれる。
なので、時間とかの問題ではなく、デッドロックを避けつつ、
必要な排他処理を過不足無く行なうために必要であれば、
condition variableを使うか、自前で同等の処理を行なうことに
なる。
mutexをロックしたまま別のmutex待ちをして良いのなら、
condition variableを使う必要は無い。
0215デフォルトの名無しさん05/01/28 03:38:10
>>214
どうもありがとうございます。

自分が考えていたのは、mutex が一時的に解放されてもそれほど嬉しく無さそうな
処理だったので、まずは mutex のみで実装してみようと思います。
0216デフォルトの名無しさん05/01/30 17:49:59

volavolavolavolavolavolavolavolavolavolaァァァァーー!
0217デフォルトの名無しさん05/01/30 18:28:51
intサイズ以下なら、volatileつければ、
マルチスレッドのときにも排他は不要ですよね?
0218デフォルトの名無しさん05/01/30 18:31:21
そうですね
0219デフォルトの名無しさん05/01/30 18:35:10
>>217
へ?
0220デフォルトの名無しさん05/01/30 18:57:20
CCSを使ってモデル化して検証する
0221定期的にこの話題出てくるな。つりだろうか ?05/01/30 21:11:48
>>217
不要だと思うなら、そうすればいい。

後で泣きを見ても知らんけどな。
0222デフォルトの名無しさん05/01/30 21:18:59
>>221
100%煽りでしょ。
せっかくの「またvolatile厨か・・・」への前振りを無駄にするな。
0223デフォルトの名無しさん05/01/31 11:01:30
またvolatile厨か・・・
0224デフォルトの名無しさん05/01/31 19:34:43
またvolatile厨厨か・・・
0225デフォルトの名無しさん05/01/31 23:11:21
coutを複数スレッドから利用する場合改行までの間で出力が混ざってしまうのは、
下記のページみたいな感じでmutexやクリティカルセクションを使ってロックするしかないの?
なんか重そうだけど。
http://www.athomejp.com/goldfish/mfc/cobject/thread.asp
0226デフォルトの名無しさん05/01/31 23:41:26
心配しないでもI/Oの方が遅い。
stringstreamの場合は工夫した方がいいと思うが。
0227デフォルトの名無しさん05/02/02 23:23:58
クリティカルセクションならカーネルレベルまで話が及ばない(ほとんどのばあい)
から重くないと思われ。
0228デフォルトの名無しさん05/02/03 01:12:21
どっちもI/Oの重さを考えたら無いようなもん。
応答性やパフォーマンスを気にするならcoutなんかやめて
非ブロッキングI/Oを使えばいい。
0229デフォルトの名無しさん05/02/03 10:36:44
キタ━━━━(゚∀゚)━━━━!! @cppll ML

>επιστημηです。
>
>で、関連事項なんすけど、スレッド間で共有する変数の類は
>Mutexなんかでガードしてないならvolatileつけとくのが無難
>なんでしょかしらやっぱ?

えぴすさんでもひっかかっちゃうのね。
0230デフォルトの名無しさん05/02/03 12:09:18
>>229
「でも」とはなんだ「でも」とは!
奴だからこそ、だろう。
0231デフォルトの名無しさん05/02/03 12:17:26
レスはもっと香ばしいけどね。レジスタがどーたらとか。
0232デフォルトの名無しさん05/02/03 12:50:58
>>229の文章ならそんな問題ないでしょう?

排他のためにやるわけじゃなくて、
最適化の抑止の事だけを話しているのかも知れないから。
十分って言っているわけじゃなくて、無難だしね。まあ、

>で、関連事項なんすけど、

何に関連していたかにも依るわけですが…
0233デフォルトの名無しさん05/02/03 13:01:08
constと同じとこにvolatileやconst volatileも書けるっていうお話でしたとさ。
0234デフォルトの名無しさん05/02/03 21:34:24
>>232
> 排他のためにやるわけじゃなくて、
> 最適化の抑止の事だけを話しているのかも知れないから。
排他が関係しないスレッド間の共有って、全スレッドがreadしかしないとかそういうこと?
確かにそれなら定数読むのとかわらんから、volatileもメモリバリアもいらないけど、そういう文脈なのかなぁ。
0235デフォルトの名無しさん05/02/04 01:21:32
しかし、最近そこかしこでmutexのかわりに/mutexに加えてvolatileって騒いでる人を見かけるんだけど
国内でだれかvolatileを布教してる人でもいるんですか?
0236デフォルトの名無しさん05/02/04 05:57:04
またvolatile厨厨か・・・
0237デフォルトの名無しさん05/02/04 06:10:36
coutを複数スレッドから利用する場合改行までの間で出力が混ざってしまうのは、
下記のページみたいな感じでmutexやクリティカルセクションを使ってロックするしかないの?
なんか重そうだけど。
http://www.athomejp.com/goldfish/mfc/cobject/thread.asp
0238デフォルトの名無しさん05/02/04 08:26:34
>>237
思い込みはどうでもいいからベンチマークとれよ
0239デフォルトの名無しさん05/02/04 09:00:25
スレッドプログラミング初心者です。
volatileはマルチスレッド対応ですか?教えてください。
0240デフォルトの名無しさん05/02/04 09:10:22
>>237
coutをvolatileにしろ
0241デフォルトの名無しさん05/02/04 09:23:38
アプリケーションがシングルスレッドである間しか書き込みしない事が分かっている場合
(スレッドが2つ以上になった時点では読込しか行わない場合)
排他処理したり、volatile修飾する必要は無いの?
0242デフォルトの名無しさん05/02/04 09:42:47
>>241
またvola (ry

えーとね、排他は必要ない。169-170の質問と実は同じ内容だから、
回答は >>192 >>195 を参照のこと。

あと、volatileはいい加減やめい。スレッドとvolatileは無関係。
0243デフォルトの名無しさん05/02/04 20:15:08
ボラボラボラボラボラボラボラボラボラタイール!
0244デフォルトの名無しさん05/02/04 22:16:44
volatileってコンパイラの想定外の理由で変数の内容が変わるので最適化の対象にしないでくれって宣言だよね?
0245デフォルトの名無しさん05/02/04 22:22:00
>>244
ウザい
0246デフォルトの名無しさん05/02/04 22:26:20
bool型の値に書込と読込を色々なスレッドから同時にするような場合排他をしない場合は、
trueに変えたはずなのにまだfalseと読み出されたりするくらいで、
いきなりスレッドが死んだりする事は無いよね?
0247デフォルトの名無しさん05/02/04 22:39:07
>>245
お前がな。
そもそもこのスレでのvolatile発言はすべて煽り。ほいほい釣られるのはやめてくれ。
0248デフォルトの名無しさん05/02/04 23:12:27
>>247
お前がな。
そもそもこのスレでのvolatile発言はすべて煽り。ほいほい釣られるのはやめてくれ。
0249デフォルトの名無しさん05/02/05 01:22:51
volatileにしてから、女の子にもてもてです。
0250デフォルトの名無しさん05/02/05 02:14:05
>>246
volatileと宣言すれば完璧です。
0251デフォルトの名無しさん05/02/05 02:43:57
volatileって飛びますよね
0252デフォルトの名無しさん05/02/05 15:08:47
volatileほいほい状態のなか申し訳がないのだが、c/c++のvolatileと
java/c#のvolatileは意味合いが違うという理解でいいのでしょうか?
普通のブラウザからなので過去スレッドに既出ならすまそ。
■ このスレッドは過去ログ倉庫に格納されています