10/10/01 18:10:07
移植性のあるコードを書こうと思ったら必要なる。
ただハードやOS・言語・コンパイラ・ライブラリなどが想定するメモリモデル
(平たく言えばマルチスレッドでメモリがどう見えるかのルール)によっては
それで正しいケースもある。
具体的な回答が欲しいならpthread、Win32のスレッド、Javaや.NETくらいの
くくりで質問するといいよ。
453:デフォルトの名無しさん
10/10/01 18:34:06
>>451
まず、書き込まれた値が化けたりせず正常に読めるか、という点については
適切にアラインされている、CPUのワードサイズ以下の値なら、まず問題ない。
Cコンパイラにおいて、「int」として扱われる値を
Cコンパイラに配置させる場合は、まず大丈夫。
ただし、スレッドAが書き換えた後にスレッドBが読み出したとき
直前の変更が適切に反映されているかどうか、については
環境依存、というか普通は保証されない。
454:デフォルトの名無しさん
10/10/01 18:41:34
一方通行なら問題ないでしょ
455:デフォルトの名無しさん
10/10/01 18:44:58
他に受け渡すデータが一切どこにも何もなくて、ただその数字1個を渡せばいいだけなら
456:デフォルトの名無しさん
10/10/01 18:49:48
ハード依存OKということならシングルCPUのPCは
スレッドに関するほとんどの問題発生しないし正常に動くね。
457:デフォルトの名無しさん
10/10/01 18:55:25
読み出しで値を比較するときはちょっと考えないといけないかも
458:デフォルトの名無しさん
10/10/01 18:57:15
>>456
いくらなんでも、理解して無さすぎ
459:デフォルトの名無しさん
10/10/01 18:57:30
>>452
すまん、VC++で、Win32APIのCreateThread使った話だった
>>453
thx 直前の変更は特に気にしなくてもよさそう
取り扱う変数がvectorとかlistになってくるとまた違うんかな……
460:デフォルトの名無しさん
10/10/01 22:14:34
ひたすらスレッドAが書き込んでスレッドBが読み出してprintfするだけなら正しく見えるが、
例えば、イベントを受け取ってスレッドAが書き込もうとして、スレッドBは読み出すとき、
読み出された値はスレッドAが書き込こむ前か後かはCPUの気まぐれになりそうな気がする。
まぁそんな時はロックしなくてもスレッドAが書き込み終わったらスレッドBに読み込むように言えばいいけど
461:デフォルトの名無しさん
10/10/01 22:32:14
Win32での32bit読み書きはアトミックな操作だっけ?
462:デフォルトの名無しさん
10/10/01 22:38:21
Windowsならここ読んどきゃいいよ
URLリンク(msdn.microsoft.com)(VS.85).aspx
URLリンク(msdn.microsoft.com)(VS.85).aspx
463:デフォルトの名無しさん
10/10/02 04:07:15
>>461
Win32の環境じゃなくIA32とかx64の意味でじゃないの?
464:デフォルトの名無しさん
10/10/02 10:36:20
i386SXのように外部データバスが16bitのものはどうなるんだろ。
i386SXでマルチプロセッサ構成は見たことがないけどね。
465:デフォルトの名無しさん
10/10/02 10:56:16
たぶん、データが化ける可能性があると思う。
386SX以外にも、68000とか8088とかがその系統だったと思うし
今後も組み込み向けとかにそういうのが出てこないとは言い切れない。
だから、「intなら大丈夫」じゃなくて「intなら普通は大丈夫」程度。
とはいえ、組み込み向けのバス幅制限があるような環境では
マルチスレッドはともかく、
マルチプロセッサ/マルチコアはまずありえないと考えて良いんじゃないかな。
466:デフォルトの名無しさん
10/10/02 11:02:40
そもそも、lock prefix使えないはずなので、マルチプロセッサが構成出来ない。
467:デフォルトの名無しさん
10/10/02 11:03:07
386SXの32ビットR/Wや8088の16ビットR/Wは、読み書きは複数サイクルかもしれないけど、
完了するまで割込まれないんじゃなかった? 仕様書見て言ってるわけじゃないけど。
同じような構成で割込まれるプロセッサもあるかもしれないけど。
468:デフォルトの名無しさん
10/10/02 11:50:37
32bitのアクセスがアトミックであると保証されてるのはi486以降とIntelの資料に書いてある
469:デフォルトの名無しさん
10/10/02 12:09:53
>>467
割り込みは確かに発生しないから単一コアのスレッドなら問題はないが、
マルチコア・CPUの場合は問題が発生する。
470:デフォルトの名無しさん
10/10/02 12:18:00
んでi386SXのマルチプロセッサやマルチコアは実在するの?
471:デフォルトの名無しさん
10/10/02 12:46:22
SXかどうかはわからないが386のマルチプロセッサはあったらしい。
URLリンク(ja.wikipedia.org)
プロセッサレベルの割込みじゃなくて、バスの読み書きがどうかということだと思うんだけど。
472:デフォルトの名無しさん
10/10/02 12:55:16
>>471
それはi386DXだな
473:デフォルトの名無しさん
10/10/02 14:15:52
ハードのことわからんのに憶測で書くなよ
474:デフォルトの名無しさん
10/10/02 15:18:15
>>468
i386まではDMA操作なら割り込めた、CPU単体でならアトミックだったがSXでマルチプロセッサ組んだらダメだろうと思う
475:デフォルトの名無しさん
10/10/02 15:22:14
小数点付きのプログラムカウンタのあるCPUでも使ってるんかね
476:デフォルトの名無しさん
10/10/02 22:16:44
>>475
パイプラインの途中を指し示したいみたいな?
477:デフォルトの名無しさん
10/10/02 23:05:16
たぶん475は、全ての命令が1クロックで実行できると思ってる。
478:デフォルトの名無しさん
10/10/02 23:52:07
intelのは1クロックで動くんじゃないの
479:デフォルトの名無しさん
10/10/02 23:58:09
ワイヤードロジックをほぼ全体に使うようになったのは486から
480:デフォルトの名無しさん
10/10/03 00:08:11
>>467
割り込みと、トランザクションをごっちゃにしてる?
CPUの割り込みはR/Wの間に中断しないだけ。
マルチプロセッサについてはRとWが別のトランザクションなんでR/Wの間に別のプロセッサのRやWが割り込める。
この割り込みを防ぐ信号を駆動するのがインターロック命令
481:デフォルトの名無しさん
10/10/03 01:17:48
URLリンク(gcc.gnu.org)
482:デフォルトの名無しさん
10/10/03 11:49:42
読む側が、変更されない変数読んでると思われて最適化されちゃうとか無いの?
volatile付けなくても大丈夫?
483:デフォルトの名無しさん
10/10/03 13:45:17
>>482
スレッド間で共有する変数はvolatileつけておくべきだよ。
484:デフォルトの名無しさん
10/10/03 14:19:19
>>483
そんないいかげんな知識で大丈夫か?
485:デフォルトの名無しさん
10/10/03 14:31:25
馬鹿は黙れ。CPUの基本構造も知らずにプログラム組むとか笑えない。
486:デフォルトの名無しさん
10/10/03 14:33:44
>>484
完璧な解説ヨロ
487:デフォルトの名無しさん
10/10/03 14:50:17
ここ読んどけ
URLリンク(d.hatena.ne.jp)
488:デフォルトの名無しさん
10/10/03 14:58:02
>>465
> とはいえ、組み込み向けのバス幅制限があるような環境では
> マルチスレッドはともかく、
> マルチプロセッサ/マルチコアはまずありえないと考えて良いんじゃないかな。
組込み マルチコア でググレばわかるように、もはや組み込みでもマルチ
コアはありえないと言える状況ではないよ。
489:デフォルトの名無しさん
10/10/03 15:10:07
8088やi386SXみたいな内部と外部でバス幅が違うような
石を使わざるを得ない(特殊な?)状況限定の話にそんなレスされても。
490:デフォルトの名無しさん
10/10/03 16:00:49
内部と外部でバス幅が違うなんて組み込みだと今時珍しくないが
もしかしてそんなことも知らんのか?
491:デフォルトの名無しさん
10/10/03 16:58:51
ハードの事わかって書いてるわけじゃないでしょ
最適化されたときのコードの矛盾とかをハードの問題みたいに思ってるのかも
492:デフォルトの名無しさん
10/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:デフォルトの名無しさん
10/10/03 20:23:30
>>492
それCでコンパイルできた?
494:デフォルトの名無しさん
10/10/03 20:29:53
>>488>>490
「バス幅が違うような環境でマルチコアなんかないだろ?」と
>>465には書かれているように見えるが
おまえ、日本語は苦手か?
両方を満たしたものがめずらしくもないものなら
そう反論しろよ。別個にではなく。
495:デフォルトの名無しさん
10/10/03 20:30:43
>>492
またお前か
496:494
10/10/03 20:38:18
ちょっと書き方を変える。
>>488
「組み込みにマルチコアはありえない」などとは、どこにも書かれてない。
偉そうにしてるが、幻覚でも見たのか?
>>490
「内部と外部でバス幅が違う環境などない」などとは、誰も言ってない。
偉そうにしてるが、電波でも受け取ったか?
「内部と外部でバス幅が違うような用途でも、マルチコアが採用されつつある」
と言いたいのなら、ちゃんとそう書け。
497:デフォルトの名無しさん
10/10/03 22:28:11
> 「組み込みにマルチコアはありえない」などとは、どこにも書かれてない。
⇒ 「マルチプロセッサ/マルチコアはまずありえない」と書いてますが?
>「内部と外部でバス幅が違う環境などない」などとは、誰も言ってない。
誰もそんなことは言ってないし、誰もそれに反論なんてしてない。
むしろ、最近は珍しくないと書いてあるんだが。
偉そうにしてるが、一体誰と戦ってるんだ? (w
498: ◆0uxK91AxII
10/10/04 23:01:18
>>484
大丈夫だ、問題無い。
499:デフォルトの名無しさん
10/10/05 22:30:40
>>498
インテルは言っている、素直にインテル・スレッディング・ビルディングブロックを使えと
500:デフォルトの名無しさん
10/10/06 01:31:55
インテルは言っている、インテルはいっている
501:デフォルトの名無しさん
10/10/06 09:05:27
エルシャダイスレはここですか?
502:デフォルトの名無しさん
10/10/06 19:27:08
だめええ!入れないでえええ!インテルいれちゃだめええええええええ!!あ?
503:デフォルトの名無しさん
10/10/06 21:54:44
インテルは逝ってる
504:デフォルトの名無しさん
10/10/10 11:00:31
スタベーションを回避する方法を教えてください。
505:デフォルトの名無しさん
10/10/12 15:22:11
待ち行列の先頭にいるスレッド以外は偶然入れても待ち行列の最後に並んで前の人が終わるまで待つとか
506:デフォルトの名無しさん
10/10/12 20:17:24
>>504
A,B,Cというセマフォを取得するときどのスレッドもA,B,Cの順でセマフォを取得する。
507:デフォルトの名無しさん
10/10/13 01:49:19
【OS】WindowsXP
【言語】C++,Win32
【実行環境】VisualStudio2005
かなり基本的な質問です。
スレッドを外部から終了させたい場合、どのようにすればいいのでしょうか?
あるスレッドを常に動かしていて、ユーザーがGUIプログラムを閉じた場合に、メインスレッド側からどのように命令すればいいのかわかりません。
URLリンク(msdn.microsoft.com)
↑のようなページやググって調べると、スレッド関数側が自発的に_endthreadex関数などで終了する例はあるのですが、
終了するタイミングをスレッド関数側が知らない場合についてはあまり書かれていません。
よろしくお願いします。
508:デフォルトの名無しさん
10/10/13 02:06:21
終了するタイミングをスレッド関数側に教える仕組みがいくつかある
509:デフォルトの名無しさん
10/10/13 06:37:16
>>507
何とかしてサブスレッドに終了を伝える方法を自分で実装する。特に関数はない。
Windowsならvolatile boolかCreateEvent+SetEventでいいだろう。
510:デフォルトの名無しさん
10/10/14 04:23:26
いいか、お前らTerminateThreadは使うなよ!使うな!絶対に使うなよ!
511:デフォルトの名無しさん
10/10/14 07:47:26
kill -KILLですね、わかります。
512:デフォルトの名無しさん
10/10/14 22:51:22
TerminateThread = ハングしろ に近いからねぇ
.Netとかだとそもそも抹消されてるが。Suspendも割と個人的に怖いな
513:デフォルトの名無しさん
10/10/14 22:52:08
TerminateThreadに頼ったプログラムは死んでいいけど、
バグがあってサブスレッドが応答しなくなった時の万が一のためにTerminateThreadするのは
いーんでないの
514:デフォルトの名無しさん
10/10/14 23:08:49
つーかスレッドの終了待ちでWaitFor*Objectしてタイムアウトしたら
TerminateThreadってのは普通だろ
515:デフォルトの名無しさん
10/10/14 23:23:24
そりはバグなので速やかにアプリケーションを終了すべきでは?
少なくとも普通じゃない。
516:デフォルトの名無しさん
10/10/14 23:43:40
>>510
別に使っても問題ないよ。
DllMainのデタッチスレッドさえちゃんと実装されていれば何も問題はない。
517:デフォルトの名無しさん
10/10/14 23:58:39
Vistaより前がターゲットに入るなら「何も問題ない」は無いわ
DllMainがどう頑張ろうと関係無い
518:デフォルトの名無しさん
10/10/15 00:15:38
>>516
DllMainはコールバックされないってちゃんと書いてあるのにどういうコードを書くつもりなのか聞きたい
519: ◆0uxK91AxII
10/10/15 04:13:54
TerminateThreadするくらいならExitProcessで止めを刺す。
520:デフォルトの名無しさん
10/10/15 04:18:38
TerminateThreadなんて使う必要性あるの?
521:デフォルトの名無しさん
10/10/15 06:53:29
サブスレッドの確保したメモリとかソケットとかDB接続とかその他もろもろのハンドル
はどうするつもりだよ。
あとミューテックスをロックしたまま暴走した場合とか開放されるんだっけ?
問題ありすぎ
522:デフォルトの名無しさん
10/10/15 23:13:04
>>514
ないない
523:デフォルトの名無しさん
10/10/15 23:13:49
>>519
そのほうがごみが残らなくていいな
524:デフォルトの名無しさん
10/12/19 17:17:41
printfはどういうレベルでスレッドセーフじゃないんでしょうか
525:デフォルトの名無しさん
10/12/19 17:19:00
間違えた、sprintfです
526:デフォルトの名無しさん
10/12/19 17:22:56
書込み先のことかな?
527:デフォルトの名無しさん
10/12/19 17:24:15
処理系によるんじゃないでしょうか
528:デフォルトの名無しさん
10/12/19 17:30:04
MT-Safe ってどういう意味?
529:デフォルトの名無しさん
10/12/19 17:30:49
複数のスレッドで安全という意味
530:デフォルトの名無しさん
10/12/19 17:32:51
>>527
POSIXというか、ぶっちゃけLinuxの標準ライブラリstdioでならどうでしょうか。
ここまで範囲限定したらスレチになんのかな?
531:デフォルトの名無しさん
10/12/19 17:35:10
POSIXのstdioで _unlocked が付いてないものはスレッドセーフです
532:デフォルトの名無しさん
10/12/19 19:46:28
つまりprintfはスレッドセーフってことか。ありがとう!
533:デフォルトの名無しさん
10/12/19 21:15:28
関数がってことで、使い方間違えると...
534:デフォルトの名無しさん
10/12/19 23:13:56
まぁ想像するだけでもprintfは外部に出力するからロックとか色々してるのは分かる
printfしたらバグが起こらなくなったとかで原因がスレッド絡みとかよくある
んでprintfで起こらなくなるから放置とかマジ勘弁してくださいorz
535:デフォルトの名無しさん
10/12/24 00:47:37
スレッドセーフなメモリの読み書きについて勉強しているのですが、情報が少なく捗りません。
メモリへの同時アクセスによるデータ破壊は、書き込み時にのみ起こると認識しているのですが、正しいでしょうか?
・二つのスレッドが一つの変数を書き換えるとき
→データが破壊される場合がある。
・一つのスレッドが一つの変数を書き換え、別のスレッドがその変数を読み込むとき
→書き込みは問題なく行われる。
→読み込みは、書き換え途中のデータを読み込む場合がある。
・二つのスレッドが一つの変数を読み込むとき
→問題なし。
536:デフォルトの名無しさん
10/12/24 01:06:26
書き込まないものを読み込むことにどんな意味があるのだろうか
537:デフォルトの名無しさん
10/12/24 01:10:53
const 定数ですね
538:デフォルトの名無しさん
10/12/24 01:43:18
>>535
いずれも正しい。
539:デフォルトの名無しさん
10/12/24 06:02:20
ありがとうございます。理解が深まりました。
540:デフォルトの名無しさん
10/12/24 09:17:21
>>535
> ・二つのスレッドが一つの変数を書き換えるとき
> →データが破壊される場合がある。
データの破壊とは何ぞや?単に後から書いたデータが残る。それだけの話。
541:デフォルトの名無しさん
10/12/24 09:53:16
それぞれの書き込みがアトミックならね。
32ビットマシンで64ビットの書き込みとか、アトミックでない場合、破壊が起こるかもしれない。
542:デフォルトの名無しさん
10/12/24 15:07:31
>>540
配列だって、立派な配列変数だぜ。
文字列型変数もあるしな。
543:540
10/12/24 15:52:35
そうだった、最近のデータはでかいんだな。
組み込み系のスレ見た後だったから頭がアセンブラレベルになってた。
失礼。
俺はどっちにしてもミューテックスかクリティカルセクションで排他しておくけど。
544:デフォルトの名無しさん
10/12/24 17:17:54
同時アクセス時の挙動なんてCPUの仕様次第だろ
同時読込なら安全なんて確証は無い
545:デフォルトの名無しさん
10/12/24 17:20:04
データが小さければ読み書きのキャッシュ問題とか無視できるが、
今はふつうに扱う標準データが大きいからなあ。プログラミングも大変だ。
546:デフォルトの名無しさん
10/12/24 17:20:27
アホ発見
547:デフォルトの名無しさん
10/12/24 17:30:42
同時読込なら安全なんて確証は無い・・・
ということは同じ関数を同時に実行するとまずい場合があるってことか
同じ関数を同時に実行すると同じ命令列を同時に読込むことになるもんな
548:デフォルトの名無しさん
10/12/25 20:23:56
言語仕様じゃなくハードウェア仕様だと理解してればいい
大丈夫かどうかを言語仕様で調べても守備範囲外のことで規定されてないから無駄
549:デフォルトの名無しさん
10/12/25 20:28:39
いや失礼、言語仕様で規定されてる物もあるか
550:デフォルトの名無しさん
10/12/26 16:17:56
printfがスレッドセーフじゃないのはわかるけど
どうしてsprintfがスレッドセーフではないのはなぜ?
551:デフォルトの名無しさん
10/12/26 16:24:32
>>550
内部にスタテックバッファーを持ってるかも。
552:デフォルトの名無しさん
10/12/26 16:54:42
>>551
まじか・・・だらしのないやつだなsprintfも・・・
553:デフォルトの名無しさん
10/12/26 17:45:40
おまえが使ってるライブラリを実装したところに聞けよ
554:デフォルトの名無しさん
10/12/26 18:09:36
sprintfがスレッドアンセーフってのはどこ情報?
555:デフォルトの名無しさん
10/12/26 19:50:50
あとだしで申し訳ないがライブラリはglibcです
>>554
URLリンク(slashcolon.com)
URLリンク(www.kmonos.net)
Dでスレッドセーフにしました=Cだとスレッドセーフちがう
と解釈しました
ていうか、そもそもprintfがスレッドセーフだという情報がない。
不明なうちはアンセーフ扱いするのが俺のジャスティス
556:デフォルトの名無しさん
10/12/26 20:00:44
なるほど
確かに
557:デフォルトの名無しさん
10/12/26 20:13:26
それ英語版見たらスレッドセーフなんてどこにも書いてないぞ・・・
> writefln() improves on printf() by being type-aware and type-safe:
誤訳じゃないのか
558:デフォルトの名無しさん
10/12/26 20:16:54
URLリンク(stackoverflow.com)
適当にぐぐったけどglibcはスレッドセーフとか書いてるような感じ
559:デフォルトの名無しさん
10/12/27 11:09:50
へえ
560:デフォルトの名無しさん
10/12/27 14:34:33
探しても「セーフだろう」「たぶんセーフ」ばっかりしか出てこない
むずむずするなぁ
561:デフォルトの名無しさん
10/12/27 15:03:50
IEEE Std 1003.1-2001の定義では、例外的にアンセーフで良いとされているもの以外は
スレッドセーフ。
URLリンク(pubs.opengroup.org)
562:デフォルトの名無しさん
10/12/28 19:19:26
過去スレ全部はみれなかったんだけど、マルチスレッド関連の良書をまとめてみる。
この他にこれがいいとかあったり、これ駄目とかあったら教えて。
[一般]
並行コンピューティング技法 ―実践マルチコア/マルチスレッドプログラミング
The Art of Multiprocessor Programming 並行プログラミングの原理から実践まで
増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編
[java]
Javaスレッドプログラミング―並列オブジェクト指向プログラミングの設計原理 (OO SELECTION)
Concurrency: State Models and Java Programs 2edition
Java並行処理プログラミング ―その「基盤」と「最新API」を究める
[windows]
Win32 マルチスレッド プログラミング
Advanced Windows 第5版 上
Advanced Windows 第5版 下
[Unix]
POSIXスレッドプログラミング
563:デフォルトの名無しさん
10/12/31 19:52:51
[C++]
インテルスレッディング・ビルディング・ブロック
主にこのライブラリの使い方だが、
他にもスレッド管理の考え方が載ってる。まぁオープンソースなので見れるのだけど
564:デフォルトの名無しさん
11/01/03 21:56:27
ありがとうございます。C++の良書をあまり知らないので助かります。
565:デフォルトの名無しさん
11/01/15 09:14:58
concurrent hashmapのC++実装って
なんでないの?
566:デフォルトの名無しさん
11/01/15 09:49:16
>>565
キミのためにお取り置きしてある。
567:デフォルトの名無しさん
11/01/15 10:31:02
>>566
並列mapでいいから実装ないの?
C++って並列コンテナないから何もできないよね
568:デフォルトの名無しさん
11/01/15 18:21:33
>>567
キミが作るだろうと思って残しておいた。
569:デフォルトの名無しさん
11/01/16 11:14:37
>>567
俺のところにはある。
570:デフォルトの名無しさん
11/01/16 11:28:44
C/C++はアセンブラと高級言語の間みたいな位置だからな
言語そのものを作るとか、OSを作るとか、リソースの厳しい組み込み系で作るとか、
そういう用途じゃないなら別に強力な言語ではない
ネイティブのCPUの挙動を理解しないとC/C++の有用性は半減すると思われ
571:デフォルトの名無しさん
11/01/25 23:02:03
すみません、spin-lockをしている間にCPUの使用率を下げる方法を知っている方はいますか?
調べてみると、rep;nop命令やSSEのpause命令をがそれに該当するように思えるのですが、
使ってみても何ら変わりませんでした。
スピンロックつかっわないとは思うんだけど。
自作のスレッドバリア関数(自作のspin_lock)を作って、
たとえば、
if(threadnum=5) sleep(10);
my_barirrer();
とするとスレッド5を待っている間は5以外のCPU使用率が100%近くなってしまいます。
それに対してOpenMP使った場合では、
if(threadnum=5) sleep(10);
#paragma omp barirrer
だと待っている間はCPU使用率は殆ど変わりません。
ちなみに自作のspinlockは下記のような感じです。
if(thread_num == 0)
{
asm volatile(
"Loop1:\n\t\t"
"movl (%0), %%eax\n\t\t"
"movl (%1), %%ebx\n\t\t"
"lfence\n\t\t"
"cmpl %%ebx, %%eax\n\t\t"
"rep;nop\n\t\t"
"jne Loop1\n\t\t"
:
:"r"(&lock->sync), "r"(&lock->maxthreads)
:"memory","%eax","%ebx"
);
というか、これって間抜けですかね?
572:デフォルトの名無しさん
11/01/25 23:10:46
自前でタスク切換えみたいなことするしか
573:デフォルトの名無しさん
11/01/25 23:15:42
>>571
>>369
574:デフォルトの名無しさん
11/01/25 23:24:51
>>573
お前友達いないだろ
575:デフォルトの名無しさん
11/01/25 23:34:47
>>571
Sleepさせりゃいいんじゃね。
576:デフォルトの名無しさん
11/01/25 23:44:45
割り込みでしか切り替わらないコードで使用率下げたいというのが
577:デフォルトの名無しさん
11/01/28 22:22:30
さむいな(´・ω・`)
578:デフォルトの名無しさん
11/01/28 22:43:23
寒稲
579:デフォルトの名無しさん
11/01/31 22:10:29
>>571
CPU使用率が100%じゃないロックなんて、スピンロックとは認めない。
580:デフォルトの名無しさん
11/02/01 00:53:40
そもそも100%じゃないってことはコンテキストスイッチしてるってことになるでしょ?
何のためのスピンロックなのよあり得ない。
581:デフォルトの名無しさん
11/02/01 10:50:42
スリープロックのループもスピン扱いすることもあるから何とも
582:デフォルトの名無しさん
11/04/04 19:37:25.20
ちょっと聞いていい?
以下のコードでnotifyAllされたらどうなるのって質問
void A()
synchronized(Lock){
if(List.size() == 0){
try{ Lock.wait(); }(Exception e){}
}
//以下処理続く
}
}
このコードで複数のスレッドが待ち状態だったらnotifyAllとき再度Lockを取りに行ってくれるの?
もし、そうだったとしたら。
結局はnotifyで1つのスレッドのみ動かすってのと同じことになるの?
それとも再起処理的に以下のようにしなきゃだめ?
void A()
synchronized(Lock){
if(List.size() == 0){
try{ Lock.wait(); }(Exception e){}
A(); ←ここでさらに再帰的に同じメソッドを呼び出す
}
//以下処理続く
}
}
おしえてエロイひと。。。
583:デフォルトの名無しさん
11/04/04 19:47:38.94
>>582
notifyAll を呼ぶと、wait してたスレッドはすべて起きて、 Lock を取りに行く
どうせみんなすぐには取れないから Lock 待ち状態になるが、すでに wait からは外れてるので、 Lock を取れた順にすべてのスレッドが動き出す
notify の場合は、wait してたスレッドのうちひとつだけが起きて Lock を取りに行く
他のスレッドは、その後 Lock が空いても、眠ったまま起きない
wait はふつう再帰じゃなくて while にする
synchronized (Lock) {
while (List.size() == 0) {
Lock.wait();
}
}
waitは、notifyされてなくても間違って起きることがあるらしいので、このように書くべきこととされている
584:デフォルトの名無しさん
11/04/04 20:17:38.60
>notifyAll を呼ぶと、wait してたスレッドはすべて起きて、 Lock を取りに行く
ということはnotifyAllでそのまま下に処理が流れていくんじゃなくて
再度 synchronized(Lock){ ←この部分に処理が戻ってくるイメージなんですかね?
別のメソッド内の以下のようなコードでnotifyAllをかけようと思ってたんだけど、
ちゃんとnumの個数分以上のスレッドは再度、wait状態に入ってくれるのか心配でした
for(int i = 0 ; i < num ; i++){
List.add(object);
}
Lock.notifyAll();
それと。
while (List.size() == 0) {
Lock.wait();
}
これしなきゃいけないんですね。Javadoc見てきました。
>>583 ありがとー。
585:デフォルトの名無しさん
11/04/04 21:55:04.24
>>584
synchronized のところまで戻るわけじゃなく、synchronized の中にいるまま、 wait のところで、
Lock をいったん解放、おやすみなサイして、起きたら元通りに取りにいく
wait は synchronized の中でありながら Lock を手放している特殊な場所
notifyAll を呼んだ側のスレッドは、notifyAll を呼んだあとそのまま下に流れていく
というのも、notifyAll を呼んだ時点では Lock は notifyAll 側のスレッドが握ってるので (synchronized 中のはず)、
wait 側のスレッドは起きるけれども、Lock を取れない
notifyAll 側が synchronized から抜けるなりして Lock を解放すると、wait 側が Lock を取って動き出せるようになる