1 名前:デフォルトの名無しさん mailto:sage [2009/09/21(月) 17:19:27 ] マルチスレッドプログラミングについて語るスレ ■前スレ マルチスレッドプログラミング相談室 その7 pc12.2ch.net/test/read.cgi/tech/1215253576/ ■過去スレ その1 ttp://pc3.2ch.net/tech/kako/997/997345868.html その2 ttp://pc5.2ch.net/test/read.cgi/tech/1037636153/ その3 ttp://pc8.2ch.net/test/read.cgi/tech/1098268137/ その4 ttp://pc8.2ch.net/test/read.cgi/tech/1130984585/ その5 ttp://pc11.2ch.net/test/read.cgi/tech/1157814833/ その6 ttp://pc11.2ch.net/test/read.cgi/tech/1187008532/ OS・言語・環境は問わないが、それゆえ明記すべし。 テンプレ 【OS】 【言語】 【実行環境】 【その他特記する事項】
451 名前:デフォルトの名無しさん [2010/10/01(金) 17:29:29 ] あんまり理解できてないのでうんこみたいな質問申し訳ないんだけど、 スレッドが二つ(A,B)あって、 変数 int a にスレッドAがひたすら数字を入れて、スレッドBはひたすらその数字を読むだけの場合、 int aの書き込み・読み込み時にクリティカルセクション使う必要はある? 手元で試してみたら片方が読み込みオンリーの場合正常に動いたんよね
452 名前:デフォルトの名無しさん mailto:sage [2010/10/01(金) 18:10:07 ] 移植性のあるコードを書こうと思ったら必要なる。 ただハードやOS・言語・コンパイラ・ライブラリなどが想定するメモリモデル (平たく言えばマルチスレッドでメモリがどう見えるかのルール)によっては それで正しいケースもある。 具体的な回答が欲しいならpthread、Win32のスレッド、Javaや.NETくらいの くくりで質問するといいよ。
453 名前:デフォルトの名無しさん mailto:sage [2010/10/01(金) 18:34:06 ] >>451 まず、書き込まれた値が化けたりせず正常に読めるか、という点については 適切にアラインされている、CPUのワードサイズ以下の値なら、まず問題ない。 Cコンパイラにおいて、「int」として扱われる値を Cコンパイラに配置させる場合は、まず大丈夫。 ただし、スレッドAが書き換えた後にスレッドBが読み出したとき 直前の変更が適切に反映されているかどうか、については 環境依存、というか普通は保証されない。
454 名前:デフォルトの名無しさん mailto:sage [2010/10/01(金) 18:41:34 ] 一方通行なら問題ないでしょ
455 名前:デフォルトの名無しさん mailto:sage [2010/10/01(金) 18:44:58 ] 他に受け渡すデータが一切どこにも何もなくて、ただその数字1個を渡せばいいだけなら
456 名前:デフォルトの名無しさん mailto:sage [2010/10/01(金) 18:49:48 ] ハード依存OKということならシングルCPUのPCは スレッドに関するほとんどの問題発生しないし正常に動くね。
457 名前:デフォルトの名無しさん mailto:sage [2010/10/01(金) 18:55:25 ] 読み出しで値を比較するときはちょっと考えないといけないかも
458 名前:デフォルトの名無しさん mailto:sage [2010/10/01(金) 18:57:15 ] >>456 いくらなんでも、理解して無さすぎ
459 名前:デフォルトの名無しさん mailto:sage [2010/10/01(金) 18:57:30 ] >>452 すまん、VC++で、Win32APIのCreateThread使った話だった >>453 thx 直前の変更は特に気にしなくてもよさそう 取り扱う変数がvectorとかlistになってくるとまた違うんかな……
460 名前:デフォルトの名無しさん mailto:sage [2010/10/01(金) 22:14:34 ] ひたすらスレッドAが書き込んでスレッドBが読み出してprintfするだけなら正しく見えるが、 例えば、イベントを受け取ってスレッドAが書き込もうとして、スレッドBは読み出すとき、 読み出された値はスレッドAが書き込こむ前か後かはCPUの気まぐれになりそうな気がする。 まぁそんな時はロックしなくてもスレッドAが書き込み終わったらスレッドBに読み込むように言えばいいけど
461 名前:デフォルトの名無しさん mailto:sage [2010/10/01(金) 22:32:14 ] Win32での32bit読み書きはアトミックな操作だっけ?
462 名前:デフォルトの名無しさん mailto:sage [2010/10/01(金) 22:38:21 ] Windowsならここ読んどきゃいいよ msdn.microsoft.com/ja-jp/library/bb310595 (VS.85).aspx msdn.microsoft.com/en-us/library/ee418650 (VS.85).aspx
463 名前:デフォルトの名無しさん mailto:sage [2010/10/02(土) 04:07:15 ] >>461 Win32の環境じゃなくIA32とかx64の意味でじゃないの?
464 名前:デフォルトの名無しさん mailto:sage [2010/10/02(土) 10:36:20 ] i386SXのように外部データバスが16bitのものはどうなるんだろ。 i386SXでマルチプロセッサ構成は見たことがないけどね。
465 名前:デフォルトの名無しさん mailto:sage [2010/10/02(土) 10:56:16 ] たぶん、データが化ける可能性があると思う。 386SX以外にも、68000とか8088とかがその系統だったと思うし 今後も組み込み向けとかにそういうのが出てこないとは言い切れない。 だから、「intなら大丈夫」じゃなくて「intなら普通は大丈夫」程度。 とはいえ、組み込み向けのバス幅制限があるような環境では マルチスレッドはともかく、 マルチプロセッサ/マルチコアはまずありえないと考えて良いんじゃないかな。
466 名前:デフォルトの名無しさん mailto:sage [2010/10/02(土) 11:02:40 ] そもそも、lock prefix使えないはずなので、マルチプロセッサが構成出来ない。
467 名前:デフォルトの名無しさん mailto:sage [2010/10/02(土) 11:03:07 ] 386SXの32ビットR/Wや8088の16ビットR/Wは、読み書きは複数サイクルかもしれないけど、 完了するまで割込まれないんじゃなかった? 仕様書見て言ってるわけじゃないけど。 同じような構成で割込まれるプロセッサもあるかもしれないけど。
468 名前:デフォルトの名無しさん mailto:sage [2010/10/02(土) 11:50:37 ] 32bitのアクセスがアトミックであると保証されてるのはi486以降とIntelの資料に書いてある
469 名前:デフォルトの名無しさん mailto:sage [2010/10/02(土) 12:09:53 ] >>467 割り込みは確かに発生しないから単一コアのスレッドなら問題はないが、 マルチコア・CPUの場合は問題が発生する。
470 名前:デフォルトの名無しさん mailto:sage [2010/10/02(土) 12:18:00 ] んでi386SXのマルチプロセッサやマルチコアは実在するの?
471 名前:デフォルトの名無しさん mailto:sage [2010/10/02(土) 12:46:22 ] SXかどうかはわからないが386のマルチプロセッサはあったらしい。 ja.wikipedia.org/wiki/%E3%82%B7%E3%83%BC%E3%82%AF%E3%82%A8%E3%83%B3%E3%83%88%E3%83%BB%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF プロセッサレベルの割込みじゃなくて、バスの読み書きがどうかということだと思うんだけど。
472 名前:デフォルトの名無しさん mailto:sage [2010/10/02(土) 12:55:16 ] >>471 それはi386DXだな
473 名前:デフォルトの名無しさん mailto:sage [2010/10/02(土) 14:15:52 ] ハードのことわからんのに憶測で書くなよ
474 名前:デフォルトの名無しさん mailto:sage [2010/10/02(土) 15:18:15 ] >>468 i386まではDMA操作なら割り込めた、CPU単体でならアトミックだったがSXでマルチプロセッサ組んだらダメだろうと思う
475 名前:デフォルトの名無しさん mailto:sage [2010/10/02(土) 15:22:14 ] 小数点付きのプログラムカウンタのあるCPUでも使ってるんかね
476 名前:デフォルトの名無しさん mailto:sage [2010/10/02(土) 22:16:44 ] >>475 パイプラインの途中を指し示したいみたいな?
477 名前:デフォルトの名無しさん mailto:sage [2010/10/02(土) 23:05:16 ] たぶん475は、全ての命令が1クロックで実行できると思ってる。
478 名前:デフォルトの名無しさん mailto:sage [2010/10/02(土) 23:52:07 ] intelのは1クロックで動くんじゃないの
479 名前:デフォルトの名無しさん mailto:sage [2010/10/02(土) 23:58:09 ] ワイヤードロジックをほぼ全体に使うようになったのは486から
480 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 00:08:11 ] >>467 割り込みと、トランザクションをごっちゃにしてる? CPUの割り込みはR/Wの間に中断しないだけ。 マルチプロセッサについてはRとWが別のトランザクションなんでR/Wの間に別のプロセッサのRやWが割り込める。 この割り込みを防ぐ信号を駆動するのがインターロック命令
481 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 01:17:48 ] ttp://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html
482 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 11:49:42 ] 読む側が、変更されない変数読んでると思われて最適化されちゃうとか無いの? volatile付けなくても大丈夫?
483 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 13:45:17 ] >>482 スレッド間で共有する変数はvolatileつけておくべきだよ。
484 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 14:19:19 ] >>483 そんないいかげんな知識で大丈夫か?
485 名前:デフォルトの名無しさん [2010/10/03(日) 14:31:25 ] 馬鹿は黙れ。CPUの基本構造も知らずにプログラム組むとか笑えない。
486 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 14:33:44 ] >>484 完璧な解説ヨロ
487 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 14:50:17 ] ここ読んどけ d.hatena.ne.jp/bsdhouse/
488 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 14:58:02 ] >>465 > とはいえ、組み込み向けのバス幅制限があるような環境では > マルチスレッドはともかく、 > マルチプロセッサ/マルチコアはまずありえないと考えて良いんじゃないかな。 組込み マルチコア でググレばわかるように、もはや組み込みでもマルチ コアはありえないと言える状況ではないよ。
489 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 15:10:07 ] 8088やi386SXみたいな内部と外部でバス幅が違うような 石を使わざるを得ない(特殊な?)状況限定の話にそんなレスされても。
490 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 16:00:49 ] 内部と外部でバス幅が違うなんて組み込みだと今時珍しくないが もしかしてそんなことも知らんのか?
491 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 16:58:51 ] ハードの事わかって書いてるわけじゃないでしょ 最適化されたときのコードの矛盾とかをハードの問題みたいに思ってるのかも
492 名前:デフォルトの名無しさん [2010/10/03(日) 19:47:54 ] 【OS】 Linux,W2K 【言語】 C 【実行環境】Cygwin(W2Kの場合) 【その他特記する事項】 以下の行列演算は高速化できるのでしょうか。 スレッドの意味も作り方もわかりません。 for(j=0;j<16;j++){ for(i=0;i<16;i++){ d1[j]^=GF[e1[j][i]]; d2[j]^=GF[e2[j][i]]; } }
493 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 20:23:30 ] >>492 それCでコンパイルできた?
494 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 20:29:53 ] >>488 >>490 「バス幅が違うような環境でマルチコアなんかないだろ?」と >>465 には書かれているように見えるが おまえ、日本語は苦手か? 両方を満たしたものがめずらしくもないものなら そう反論しろよ。別個にではなく。
495 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 20:30:43 ] >>492 またお前か
496 名前:494 mailto:sage [2010/10/03(日) 20:38:18 ] ちょっと書き方を変える。 >>488 「組み込みにマルチコアはありえない」などとは、どこにも書かれてない。 偉そうにしてるが、幻覚でも見たのか? >>490 「内部と外部でバス幅が違う環境などない」などとは、誰も言ってない。 偉そうにしてるが、電波でも受け取ったか? 「内部と外部でバス幅が違うような用途でも、マルチコアが採用されつつある」 と言いたいのなら、ちゃんとそう書け。
497 名前:デフォルトの名無しさん mailto:sage [2010/10/03(日) 22:28:11 ] > 「組み込みにマルチコアはありえない」などとは、どこにも書かれてない。 ⇒ 「マルチプロセッサ/マルチコアはまずありえない」と書いてますが? >「内部と外部でバス幅が違う環境などない」などとは、誰も言ってない。 誰もそんなことは言ってないし、誰もそれに反論なんてしてない。 むしろ、最近は珍しくないと書いてあるんだが。 偉そうにしてるが、一体誰と戦ってるんだ? (w
498 名前: ◆0uxK91AxII mailto:sage [2010/10/04(月) 23:01:18 ] >>484 大丈夫だ、問題無い。
499 名前:デフォルトの名無しさん mailto:sage [2010/10/05(火) 22:30:40 ] >>498 インテルは言っている、素直にインテル・スレッディング・ビルディングブロックを使えと
500 名前:デフォルトの名無しさん mailto:sage [2010/10/06(水) 01:31:55 ] インテルは言っている、インテルはいっている
501 名前:デフォルトの名無しさん mailto:sage [2010/10/06(水) 09:05:27 ] エルシャダイスレはここですか?
502 名前:デフォルトの名無しさん mailto:sage [2010/10/06(水) 19:27:08 ] だめええ!入れないでえええ!インテルいれちゃだめええええええええ!!あ?
503 名前:デフォルトの名無しさん mailto:sage [2010/10/06(水) 21:54:44 ] インテルは逝ってる
504 名前:デフォルトの名無しさん mailto:sage [2010/10/10(日) 11:00:31 ] スタベーションを回避する方法を教えてください。
505 名前:デフォルトの名無しさん mailto:sage [2010/10/12(火) 15:22:11 ] 待ち行列の先頭にいるスレッド以外は偶然入れても待ち行列の最後に並んで前の人が終わるまで待つとか
506 名前:デフォルトの名無しさん mailto:sage [2010/10/12(火) 20:17:24 ] >>504 A,B,Cというセマフォを取得するときどのスレッドもA,B,Cの順でセマフォを取得する。
507 名前:デフォルトの名無しさん [2010/10/13(水) 01:49:19 ] 【OS】WindowsXP 【言語】C++,Win32 【実行環境】VisualStudio2005 かなり基本的な質問です。 スレッドを外部から終了させたい場合、どのようにすればいいのでしょうか? あるスレッドを常に動かしていて、ユーザーがGUIプログラムを閉じた場合に、メインスレッド側からどのように命令すればいいのかわかりません。 ttp://msdn.microsoft.com/ja-jp/library/kdzttdcb%28VS.80%29.aspx ↑のようなページやググって調べると、スレッド関数側が自発的に_endthreadex関数などで終了する例はあるのですが、 終了するタイミングをスレッド関数側が知らない場合についてはあまり書かれていません。 よろしくお願いします。
508 名前:デフォルトの名無しさん mailto:sage [2010/10/13(水) 02:06:21 ] 終了するタイミングをスレッド関数側に教える仕組みがいくつかある
509 名前:デフォルトの名無しさん mailto:sage [2010/10/13(水) 06:37:16 ] >>507 何とかしてサブスレッドに終了を伝える方法を自分で実装する。特に関数はない。 Windowsならvolatile boolかCreateEvent+SetEventでいいだろう。
510 名前:デフォルトの名無しさん mailto:sage [2010/10/14(木) 04:23:26 ] いいか、お前らTerminateThreadは使うなよ!使うな!絶対に使うなよ!
511 名前:デフォルトの名無しさん mailto:sage [2010/10/14(木) 07:47:26 ] kill -KILLですね、わかります。
512 名前:デフォルトの名無しさん mailto:sage [2010/10/14(木) 22:51:22 ] TerminateThread = ハングしろ に近いからねぇ .Netとかだとそもそも抹消されてるが。Suspendも割と個人的に怖いな
513 名前:デフォルトの名無しさん mailto:sage [2010/10/14(木) 22:52:08 ] TerminateThreadに頼ったプログラムは死んでいいけど、 バグがあってサブスレッドが応答しなくなった時の万が一のためにTerminateThreadするのは いーんでないの
514 名前:デフォルトの名無しさん mailto:sage [2010/10/14(木) 23:08:49 ] つーかスレッドの終了待ちでWaitFor*Objectしてタイムアウトしたら TerminateThreadってのは普通だろ
515 名前:デフォルトの名無しさん mailto:sage [2010/10/14(木) 23:23:24 ] そりはバグなので速やかにアプリケーションを終了すべきでは? 少なくとも普通じゃない。
516 名前:デフォルトの名無しさん mailto:sage [2010/10/14(木) 23:43:40 ] >>510 別に使っても問題ないよ。 DllMainのデタッチスレッドさえちゃんと実装されていれば何も問題はない。
517 名前:デフォルトの名無しさん mailto:sage [2010/10/14(木) 23:58:39 ] Vistaより前がターゲットに入るなら「何も問題ない」は無いわ DllMainがどう頑張ろうと関係無い
518 名前:デフォルトの名無しさん mailto:sage [2010/10/15(金) 00:15:38 ] >>516 DllMainはコールバックされないってちゃんと書いてあるのにどういうコードを書くつもりなのか聞きたい
519 名前: ◆0uxK91AxII mailto:sage [2010/10/15(金) 04:13:54 ] TerminateThreadするくらいならExitProcessで止めを刺す。
520 名前:デフォルトの名無しさん mailto:sage [2010/10/15(金) 04:18:38 ] TerminateThreadなんて使う必要性あるの?
521 名前:デフォルトの名無しさん mailto:sage [2010/10/15(金) 06:53:29 ] サブスレッドの確保したメモリとかソケットとかDB接続とかその他もろもろのハンドル はどうするつもりだよ。 あとミューテックスをロックしたまま暴走した場合とか開放されるんだっけ? 問題ありすぎ
522 名前:デフォルトの名無しさん mailto:sage [2010/10/15(金) 23:13:04 ] >>514 ないない
523 名前:デフォルトの名無しさん mailto:sage [2010/10/15(金) 23:13:49 ] >>519 そのほうがごみが残らなくていいな
524 名前:デフォルトの名無しさん mailto:sega [2010/12/19(日) 17:17:41 ] printfはどういうレベルでスレッドセーフじゃないんでしょうか
525 名前:デフォルトの名無しさん mailto:sage [2010/12/19(日) 17:19:00 ] 間違えた、sprintfです
526 名前:デフォルトの名無しさん mailto:sage [2010/12/19(日) 17:22:56 ] 書込み先のことかな?
527 名前:デフォルトの名無しさん mailto:sage [2010/12/19(日) 17:24:15 ] 処理系によるんじゃないでしょうか
528 名前:デフォルトの名無しさん mailto:sage [2010/12/19(日) 17:30:04 ] MT-Safe ってどういう意味?
529 名前:デフォルトの名無しさん mailto:sage [2010/12/19(日) 17:30:49 ] 複数のスレッドで安全という意味
530 名前:デフォルトの名無しさん mailto:sage [2010/12/19(日) 17:32:51 ] >>527 POSIXというか、ぶっちゃけLinuxの標準ライブラリstdioでならどうでしょうか。 ここまで範囲限定したらスレチになんのかな?
531 名前:デフォルトの名無しさん mailto:sage [2010/12/19(日) 17:35:10 ] POSIXのstdioで _unlocked が付いてないものはスレッドセーフです
532 名前:デフォルトの名無しさん mailto:sage [2010/12/19(日) 19:46:28 ] つまりprintfはスレッドセーフってことか。ありがとう!
533 名前:デフォルトの名無しさん mailto:sage [2010/12/19(日) 21:15:28 ] 関数がってことで、使い方間違えると...
534 名前:デフォルトの名無しさん mailto:sage [2010/12/19(日) 23:13:56 ] まぁ想像するだけでもprintfは外部に出力するからロックとか色々してるのは分かる printfしたらバグが起こらなくなったとかで原因がスレッド絡みとかよくある んでprintfで起こらなくなるから放置とかマジ勘弁してくださいorz
535 名前:デフォルトの名無しさん mailto:sage [2010/12/24(金) 00:47:37 ] スレッドセーフなメモリの読み書きについて勉強しているのですが、情報が少なく捗りません。 メモリへの同時アクセスによるデータ破壊は、書き込み時にのみ起こると認識しているのですが、正しいでしょうか? ・二つのスレッドが一つの変数を書き換えるとき →データが破壊される場合がある。 ・一つのスレッドが一つの変数を書き換え、別のスレッドがその変数を読み込むとき →書き込みは問題なく行われる。 →読み込みは、書き換え途中のデータを読み込む場合がある。 ・二つのスレッドが一つの変数を読み込むとき →問題なし。
536 名前:デフォルトの名無しさん mailto:sage [2010/12/24(金) 01:06:26 ] 書き込まないものを読み込むことにどんな意味があるのだろうか
537 名前:デフォルトの名無しさん mailto:sage [2010/12/24(金) 01:10:53 ] const 定数ですね
538 名前:デフォルトの名無しさん mailto:sage [2010/12/24(金) 01:43:18 ] >>535 いずれも正しい。
539 名前:デフォルトの名無しさん mailto:sage [2010/12/24(金) 06:02:20 ] ありがとうございます。理解が深まりました。
540 名前:デフォルトの名無しさん mailto:sage [2010/12/24(金) 09:17:21 ] >>535 > ・二つのスレッドが一つの変数を書き換えるとき > →データが破壊される場合がある。 データの破壊とは何ぞや?単に後から書いたデータが残る。それだけの話。
541 名前:デフォルトの名無しさん mailto:sage [2010/12/24(金) 09:53:16 ] それぞれの書き込みがアトミックならね。 32ビットマシンで64ビットの書き込みとか、アトミックでない場合、破壊が起こるかもしれない。
542 名前:デフォルトの名無しさん mailto:sage [2010/12/24(金) 15:07:31 ] >>540 配列だって、立派な配列変数だぜ。 文字列型変数もあるしな。
543 名前:540 mailto:sage [2010/12/24(金) 15:52:35 ] そうだった、最近のデータはでかいんだな。 組み込み系のスレ見た後だったから頭がアセンブラレベルになってた。 失礼。 俺はどっちにしてもミューテックスかクリティカルセクションで排他しておくけど。
544 名前:デフォルトの名無しさん mailto:sage [2010/12/24(金) 17:17:54 ] 同時アクセス時の挙動なんてCPUの仕様次第だろ 同時読込なら安全なんて確証は無い
545 名前:デフォルトの名無しさん [2010/12/24(金) 17:20:04 ] データが小さければ読み書きのキャッシュ問題とか無視できるが、 今はふつうに扱う標準データが大きいからなあ。プログラミングも大変だ。
546 名前:デフォルトの名無しさん mailto:sage [2010/12/24(金) 17:20:27 ] アホ発見
547 名前:デフォルトの名無しさん mailto:sage [2010/12/24(金) 17:30:42 ] 同時読込なら安全なんて確証は無い・・・ ということは同じ関数を同時に実行するとまずい場合があるってことか 同じ関数を同時に実行すると同じ命令列を同時に読込むことになるもんな
548 名前:デフォルトの名無しさん mailto:sage [2010/12/25(土) 20:23:56 ] 言語仕様じゃなくハードウェア仕様だと理解してればいい 大丈夫かどうかを言語仕様で調べても守備範囲外のことで規定されてないから無駄
549 名前:デフォルトの名無しさん mailto:sage [2010/12/25(土) 20:28:39 ] いや失礼、言語仕様で規定されてる物もあるか
550 名前:デフォルトの名無しさん [2010/12/26(日) 16:17:56 ] printfがスレッドセーフじゃないのはわかるけど どうしてsprintfがスレッドセーフではないのはなぜ?
551 名前:デフォルトの名無しさん mailto:sage [2010/12/26(日) 16:24:32 ] >>550 内部にスタテックバッファーを持ってるかも。