1 名前:デフォルトの名無しさん mailto:sage [2007/08/13(月) 21:35:32 ] マルチスレッドプログラミングについて語るスレ。 その1 pc3.2ch.net/tech/kako/997/997345868.html その2 pc5.2ch.net/test/read.cgi/tech/1037636153/ その3 pc8.2ch.net/test/read.cgi/tech/1098268137/ その4 pc8.2ch.net/test/read.cgi/tech/1130984585/ その5 pc11.2ch.net/test/read.cgi/tech/1157814833/ OS・言語・環境は問わないが、それゆえ明記すべし。 テンプレ 【OS】 【言語】 【実行環境】 【その他突起する事項】
359 名前:デフォルトの名無しさん mailto:sage [2008/01/13(日) 19:16:03 ] spin lock
360 名前:デフォルトの名無しさん [2008/01/13(日) 20:38:31 ] >>359 fairnessの問題はどうする?
361 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 13:48:04 ] fairlock
362 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 18:00:45 ] 【OS】Windows Vista Ultimate 【言語】C++ 【実行環境】Visual C++ 2005 Professional, C++ Boost Library 1.34.1 【その他突起する事項】なし bool shouldExit_; istream &is; void handler() { while(!shouldExit_) { string str; is >> str; } } handler関数がthreadのコールバック関数になるのですが この関数を終了させようとしてshouldExit_にtrueを代入しても 入力が内場合、入力演算子を使用しているところでずっと待機してしまいます。 このスレッドを安全に終了させる方法はないでしょうか?
363 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 18:06:54 ] >>362 volatile bool shouldExit_=false;
364 名前:306 mailto:sage [2008/01/14(月) 18:08:38 ] すみません。 漏れていました。 本来のコードには書いてあるのですが、shouldExit_を評価するところまで処理を持って行けません・・・。
365 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 18:09:13 ] >>363 をいをい w is>>str; でブロックされてるんだからこの場合フラグは関係ないだろ。 とりあえず入力をタイムアウト付きでやるか(C++でどうやるかは知らん)、 可能なら入力ストリームをクローズしてしまえ。
366 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 18:51:35 ] 入力を待つけどキャンセルとか強制終了出来るようにしたいんだろ?
367 名前:361 mailto:sage [2008/01/14(月) 19:55:45 ] >>365 istreamの実態はネットワークなので まさにその方法でうまくいきました。 ありがとうございます。 >>366 もしそれができればそうしたいです。 なるべくstreamに影響を与えたくないです。
368 名前:デフォルトの名無しさん [2008/01/14(月) 22:15:59 ] 【OS】 linux fedora 7 【言語】 C 【実行環境】 えー?何て書けばいいのかな? 【その他突起する事項】 特になし 質問ですが、何故pthread_createの第4引数はvoidでキャストするの? argを入れるんだし。たとえば、整数 2を入れる場合も (void *)2 みたいに渡しますよね。 構造体に渡すと言ってもポインタで渡したら良いだけのような.... そのまま入れたらダメな理由は何ですか? 教えてえろい人
369 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 22:29:32 ] なにをやろうとしているかを理解してからやれ、ということ
370 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 22:31:38 ] そういう関数作って そのままいれてみろ
371 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 22:32:38 ] >>368 日本語でおkだよ
372 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 22:34:33 ] >>368 32bitで済むなら、キャストして無理やり渡したほうが楽ジャン
373 名前:デフォルトの名無しさん [2008/01/14(月) 22:35:30 ] >>369-370 あ、ありがとう。 理解が足りないかもですね。 (int *)でも良いんじゃないですか?って思うんです。 やってみたけど、ダメだよー なんです。orz
374 名前:デフォルトの名無しさん [2008/01/14(月) 22:36:23 ] あ、64bit環境 gccです
375 名前:368 [2008/01/14(月) 22:37:13 ] 373,374も私です。
376 名前:デフォルトの名無しさん [2008/01/14(月) 22:39:18 ] LP64環境か。なら、(void*)2ULLじゃねーの?
377 名前:デフォルトの名無しさん [2008/01/14(月) 22:40:18 ] void* argを数値に戻すときは、int i = (int)(unsigned long long)arg;
378 名前:368 [2008/01/14(月) 22:47:29 ] >376 (void*)2 で動きます。 プリプロセッサがそのように直しているのかも知れません。 >>377 ん? pthread_create(&th , arg2 , arg3, (void *)2); みたいに渡しますが pthread_create(&th , arg2 , arg3, (int *)2); ではダメな理由は何ですか?
379 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 22:47:42 ] uint64_tって書けよw
380 名前:368 [2008/01/14(月) 22:50:20 ] uint64_tもダメでした キチンとかかず、ごめんなさい
381 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 22:53:52 ] >>380 お前だめだわ pthread_create()のmanみて 引数の定義どうなってるか調べたか? そこは何でも受け取れるようにvoid *になってるから そう渡せやって定義に書いてあるだろボケ 東京湾に沈めるぞドあほ
382 名前:368 [2008/01/14(月) 22:57:43 ] >>381 man見てますよ。 なぜvoidでキャストするの?int*とかでも良いでしょ?ポインタで渡すだけでしょ? ってことなんです。
383 名前:368 [2008/01/14(月) 22:59:01 ] ポインタで渡す限りintもcharもvoidも関係ないでしょ?って質問です
384 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 23:00:55 ] >>382 なんでint *なの? 汎用ポインタならvoid *が判りやすくていいじゃん。 # それとも、qsort()も使ったことがない人?
385 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 23:01:29 ] C言語の型って何のためにあるかわかる?
386 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 23:06:28 ] 関係ないけどC99では整数⇔ポインタ変換する場合はintptr_tを使った方がよくて、 それやらないと最悪strict aliasingの最適化でバグっちゃうケースがあるらしい。
387 名前:368 [2008/01/14(月) 23:08:43 ] >>384 >汎用ポインタならvoid * 大抵、そうですね。 昔、voidに型は無い、という話だったけど、void型という型になっていて浦島 状態です。 >>385 話の流れから、メモリ確保の為。 intのサイズは小さく、他に大きなサイズの時困るって事でしょうけど。 今回は、pthread_create(&th , arg2 , arg3, (int *)2); のように、サイズが小さくても、不整合は出ないような... 出るのかな?
388 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 23:13:41 ] いや、Cにはvoid型はないけどvoid*型はあるの。
389 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 23:17:11 ] void型はあるよ。 void型へのキャストもできるし。
390 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 23:17:48 ] >>387 サイズ云々はかんけーねーだろ 8byteの汎用アドレス渡すことに 何一々屁理屈こねてるんだアスペル房?
391 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 23:20:22 ] >>368 あるよ
392 名前:368 [2008/01/14(月) 23:20:31 ] >>390 >385は何のため? >>389 void型って、出来てますよね?
393 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 23:20:42 ] >>387 考えがアセンブラだなぁ。 ひょっとして今時オブジェクト指向を理解できてない人?
394 名前:368 [2008/01/14(月) 23:22:59 ] >>393 確かに gcc -Sのコード見たほうがデバッグ早いです。 オブジェクト指向は、時々する程度です
395 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 23:23:51 ] >>392 厳密に型が決まってる言語だから その場合に曖昧さを表現するには C言語の場合、簡単な解決方法は void *で表現すること 理解できないみたいだし四ねw
396 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 23:27:08 ] void hoge(void) { return (void)0; } 規格にも void type とかいう用語は出てくる。
397 名前:デフォルトの名無しさん [2008/01/14(月) 23:27:48 ] >>395 理解しますが >簡単な解決方法void *で表現 ならば、他に方法は有るのですか?無いのですか?
398 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 23:31:34 ] 値は同じでも意味が違うものってあるでしょ。 C言語でいうなら同じ0でも、数学の0と、ポインタのNULLでは意味が違う。 それらを区別するために型という概念がある。 で型があることでコンパイル時に型チェックが可能となって意味の混同が起こってないかを調べられるわけ。
399 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 23:35:53 ] 引数に int* ってあるなら、それは32bitの値へのアドレスを渡すということではなくて intの意味を持ったものへのポインタを渡すって理解すべきなの。 だからそこへとある構造体へのポインタを渡すなんてのは設計も使い方も分裂症気味におかしいわけ。
400 名前:368 [2008/01/14(月) 23:43:00 ] >>398 ,399 なるへそ。分かりました。 けど、別の疑問が、**(ポインタのポインタ)で渡したら型の意味もないような
401 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 23:45:46 ] どうでもいいけど、(void *)2はともかく、(int *)2はきもい
402 名前:デフォルトの名無しさん mailto:sage [2008/01/14(月) 23:51:41 ] *が何個付こうが話は同じ
403 名前:368 [2008/01/14(月) 23:59:01 ] 了解。 皆さんありがとうーーーーー。 関数作ってみようか考えていましたが、しなくて良いみたいですね
404 名前:デフォルトの名無しさん mailto:sage [2008/01/15(火) 00:31:43 ] やけにスレが伸びてるなと思ったらC言語講習会かよ・・・
405 名前:デフォルトの名無しさん [2008/01/15(火) 00:34:54 ] じゃ、pthread_atfork関係でもする?
406 名前:デフォルトの名無しさん [2008/01/15(火) 00:37:40 ] pthread_yield()で頼む。 NPだけど。
407 名前:デフォルトの名無しさん mailto:sage [2008/01/15(火) 00:44:56 ] なんで?
408 名前:デフォルトの名無しさん mailto:sage [2008/01/16(水) 01:36:25 ] スレッドで thread1 thread2の2つを走らせている場合 正常狩猟、異常終了両方で2つのthread1 thread2とも同時に終了させて 再度、起動したいのですが、どのようにして終了させたら安全ですか? pthread_cancel(),ptrhread_join,pthread_exit
409 名前:デフォルトの名無しさん mailto:sage [2008/01/16(水) 02:31:14 ] >>408 スレッドを抜ける
410 名前:デフォルトの名無しさん mailto:sage [2008/01/16(水) 04:51:33 ] >>409 そりゃそうだ。 cancel-join exit-joinが良いのかな? どうしたら良いかな? mutexは無しです
411 名前:デフォルトの名無しさん mailto:sage [2008/01/16(水) 11:27:19 ] thread10個起動して、全部待ちたいときはどうすればいいの?
412 名前:デフォルトの名無しさん mailto:sage [2008/01/16(水) 11:33:00 ] forでjoin回せば。Win32なら64個までの限定だけどWaitForMultipleObjectsとかあるけど
413 名前:デフォルトの名無しさん mailto:sage [2008/01/16(水) 11:37:22 ] >>411 pthread_barrier_wait()
414 名前:デフォルトの名無しさん mailto:sage [2008/01/16(水) 21:02:03 ] あざーす。
415 名前:デフォルトの名無しさん mailto:sage [2008/01/17(木) 00:19:01 ] すみません スレッドでがんがん動く関数がるけど、この関数は起動字にも動いて処理します。 起動字はスレッド起こしてないんだけどpthread_関係が入っている関数を使っていいの? 具体的にはpthread_atporkです
416 名前:デフォルトの名無しさん mailto:sage [2008/01/17(木) 00:58:36 ] 誤時がおおおいな
417 名前:デフォルトの名無しさん mailto:sage [2008/01/17(木) 01:38:20 ] あっとぽーくなんてマニアックな関数、何に使うんだか。
418 名前:デフォルトの名無しさん mailto:sage [2008/01/18(金) 01:50:30 ] deadbeefと関連がありそうだな なさそうでもあるな
419 名前:デフォルトの名無しさん mailto:sage [2008/01/18(金) 22:47:59 ] >>413 411じゃないけど、pthread_barrier_wait() はlinuxでは無いようです。 どうようの効果を期待できる関数は何ですか?あるいは、その組み合わせは? 教えてちゃんですまそん
420 名前:デフォルトの名無しさん mailto:sage [2008/01/18(金) 23:57:18 ] >>419 あんたの使ってるディストリビューションが古いだけ。 もっと新しいglibcを積んでるやつを使え。
421 名前:デフォルトの名無しさん [2008/01/19(土) 00:46:44 ] LinuxThreadsの頃からあったと思うんだがな。。。 何使ってんだ??
422 名前:デフォルトの名無しさん [2008/01/19(土) 00:48:06 ] >>419 ほんとにないなら、mutexと条件変数の組み合わせで実現できるけど、結構難しいよ。 NPTLのpthread_barrier_waitの実装を読んで、真似するのが良いと思う。
423 名前:419 mailto:sage [2008/01/19(土) 02:35:01 ] >>420 ,421 cg-linuxていうらしいです。manで無かったんです かえたらダメだと思います。多分。 kernel=2.4.17?みたいなことします。 pthread.hを見て本当にないか見てみます。 >>422 そんなドキュメントあるんですか、本当になかったら探します。
424 名前:デフォルトの名無しさん [2008/01/19(土) 06:58:09 ] 私が小学生の頃、 日本中でノストラダムスの予言が大流行していた。 「1999年の7月に人類は滅亡する!」 という例のお騒がせ終末予言である。 大人になって社会に出て働きだして、 あくせくと忙しく日々を過ごしながら、 1999年は、 ありふれた日常の中であっさりと過ぎていった。 人類は滅ばなかった。 これからここで、 1999年に起こるかもしれなかった人類の壊滅的破局を、 誰にも知られずにこっそりと回避させた人たちがいた... という設定で、 荒唐無稽なストーリーを描いてみたい。 無論、100%完全なフィクションである。 www5.diary.ne.jp/logdisp.cgi?user=532063&log=200705
425 名前:デフォルトの名無しさん mailto:sage [2008/01/20(日) 00:09:05 ] >>423 www.google.co.jp/codesearch?hl=ja&lr=&q=glibc-2.5%2Fnptl%2Fsysdeps%2Fpthread%2Fpthread_barrier_wait.c とかのことね。
426 名前:デフォルトの名無しさん mailto:sage [2008/01/23(水) 02:29:53 ] >>425 くーーー、64bitなんですーーー 探してみますーーーー こんなサービスもあっ短だメモメモ
427 名前:デフォルトの名無しさん mailto:sage [2008/01/23(水) 05:25:11 ] bit数関係あんの?
428 名前:デフォルトの名無しさん mailto:sage [2008/01/23(水) 14:35:26 ] cglinuxってキャリアグレード?
429 名前:デフォルトの名無しさん mailto:sage [2008/01/24(木) 00:25:00 ] そうだろうね。カーネルバージョン見ると MontaVista っぽい。 だとするなら、サポートしてるかどうかはもんたに聞いた方が良いね。 というか、419が欲しい機能は本当にpthread_barrier_waitで合ってるんだよね? >>411 を素直に読むと >>412 で FA だと思うんだが。 (まあ419がちゃんとわかってて聞いてるなら余計なお世話だけど)
430 名前:デフォルトの名無しさん mailto:sage [2008/01/24(木) 15:23:46 ] matrix * matrixをpthread_createとpthraed_joinだけで、 ぶん回してみたけど(quad core)普通にthread無しで やるほうがはるかに早かった。 pthread_createのコストが高いのかなあ? threadを最初に作っておいてpthraed_cond_wait待っておいてスレッドを使いまわす 方式で再実装してみる。
431 名前:デフォルトの名無しさん mailto:sage [2008/01/24(木) 15:55:51 ] スレッド数4にしてる?
432 名前:デフォルトの名無しさん mailto:sage [2008/01/24(木) 16:25:48 ] している/いろいろやってみだ。 4,10,,12,16,32 32だと、たまーにtopでみていると2000%とかになっていた。 それでも、遅い。
433 名前:デフォルトの名無しさん mailto:sage [2008/01/24(木) 16:27:54 ] ×みだ ○みた あと、スレッド数8が抜けていた。
434 名前:デフォルトの名無しさん mailto:sage [2008/01/24(木) 19:28:15 ] コアが4個なんだからそれより多くしてもほとんどメリットはないだろ
435 名前:デフォルトの名無しさん mailto:sage [2008/01/24(木) 19:31:44 ] プロセス生成に比べるとマシってだけで、 スレッドの作成(と終了)はそれなりにコスト高いよ。
436 名前:デフォルトの名無しさん mailto:sage [2008/01/24(木) 19:36:38 ] 並列化効率とかアムダールの法則とかでググれ
437 名前:デフォルトの名無しさん mailto:sage [2008/01/24(木) 23:34:00 ] DualCoreXeon*2で実験した限りでは、core辺り処理量は(殆ど)変わらなかったけどなぁ。 分割の仕方が悪いんで内科医?
438 名前:デフォルトの名無しさん mailto:sage [2008/01/25(金) 06:20:13 ] >>436 そんなの、スレッド本の第一章に書いてあるだろ。
439 名前:デフォルトの名無しさん [2008/01/26(土) 13:54:13 ] Windowsで 4つのスレッドを開始させ、 一つのスレッドが終了次第、 ほかのスレッドも全て終了させる方法ってありますか?
440 名前:デフォルトの名無しさん mailto:sage [2008/01/26(土) 14:02:01 ] >>439 そのように作ればそうなります。
441 名前:デフォルトの名無しさん mailto:sage [2008/01/26(土) 14:07:17 ] >>440 すみません。 私の聞き方が曖昧でした。 手段を教えて下さい。
442 名前:デフォルトの名無しさん mailto:sage [2008/01/26(土) 14:31:08 ] 終了すると終了させるは微妙だが大きな違い
443 名前:デフォルトの名無しさん mailto:sage [2008/01/26(土) 14:37:11 ] >>439 4人の子供のうち、誰か一人でも死んだという通知が来たなら、他の三人に死亡要求を掛ければよろしいかと。 子供が死亡要求を聞き届けてくれない仕様ならば、殺すしかありませんが。 いずれにしても、APIレベルで実装したいならAPIスレ、.Netでやりたいなら.Netスレ、そうでないならVSスレなり 初心者スレなり適当にどうぞ。
444 名前:デフォルトの名無しさん mailto:sage [2008/01/26(土) 14:41:02 ] WaitForMultipleObjectsで4つのスレッドを待てば、どれか一つのスレッドが 終了したかが判るから、あとは終了イベントたてるなり(スレッドが参照していることが条件だけど)、 TerminateThreadするなり(非推奨)、好きなようにやれば。
445 名前:デフォルトの名無しさん mailto:sage [2008/01/26(土) 14:54:02 ] マルチスレッド使って、CPU負荷分担みたいなことってできる? 2つのまったく動作が同じスレッド作って、2つのCPUリソースに処理を振り分けるとか?
446 名前:デフォルトの名無しさん mailto:sage [2008/01/26(土) 15:25:58 ] できるできないで言えば普通できるに決まっとろう。
447 名前:デフォルトの名無しさん mailto:sage [2008/01/26(土) 16:19:18 ] なにか共通で使うリソースがあって、同時にそれを使えない場合は、 如何に競合を回避するか考えないと、相手のリソース解放を待つのとかで、 同時に動作できる時間が減っちゃう。 CPU1: *-*-* ***--- CPU2: -*-*- とか ---*** こんなのになったら意味無いし。
448 名前:デフォルトの名無しさん mailto:sage [2008/01/26(土) 18:09:47 ] 無駄だけどセマフォしかないわ、全部持つか、一個なら諦めろw
449 名前:デフォルトの名無しさん [2008/01/26(土) 21:55:22 ] Windowsでは、有限バッファ問題(生産者消費者問題)はどう解決するのが良いでしょうか? www.cs.is.noda.tus.ac.jp/~mune/oop/node16.html 生産者も消費者も単一プロセス内のスレッドで、生産者・消費者はそれぞれ複数いるという 状況です。バッファがfullまたはemptyのときは、pushまたはpopの処理がブロックしてかま いませんが、バッファ長は1や2ではなくもう少し大きくしたいと思っています。 UNIXだと、条件変数かセマフォを使えば簡単に実装できると思いますが、前者はWindowsには 無く、後者は単一プロセス内の同期として用いるのは効率が悪そうです。 Windowsは、VistaではなくXPを使っています。よろしくおねがいします。
450 名前:デフォルトの名無しさん [2008/01/26(土) 23:22:41 ] 何でもマルチスレッドにしたがるバカw
451 名前:デフォルトの名無しさん mailto:sage [2008/01/26(土) 23:32:11 ] >>449 XPには条件変数は無いから。自分で作る。
452 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 00:24:29 ] 条件変数って何があれば自作できるんだっけ?
453 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 00:30:14 ] Mutex/CriticalSectionとEventと変数でいいんじゃねーの?
454 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 00:40:01 ] >>453 おそらくその組み合わせでは条件変数もどきは作れないと思うのだが・・。 でも、もし大丈夫だとされている実装とか、MS推奨の実装を知っていたら教えて。
455 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:00:10 ] できないと思う理由を書いてくれ。 なんか、条件変数に過大な期待をしてるみたいだから。
456 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:10:01 ] broadcast考えなきゃ、Auto Reset Eventを SignalObjectAndWaitで待てば済む話じゃね?
457 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:23:45 ] >>455 Mutexの開放とEvent待ちをアトミックに行うことができないから。 たとえばここ docs.sun.com/app/docs/doc/819-0390/6n2qp46ef?a=view の一番下にあるようなコードの、pthread_mutexをCriticalSectionに置き換えて、 pthread_condを自動リセットのEventに置き換えたとすると、 バッファが空の状態で、スレッドAがデータを取り出そうとする Event待ちの寸前でコンテキストスイッチ まだバッファが空の状態で、スレッドBがデータを取り出そうとする Event待ちの寸前でコンテキストスイッチ スレッドCがデータを投入 スレッドCがSetEvent スレッドCが再度データを投入 スレッドCがSetEvent スレッドAがイベント待ちに入り、すぐ戻る スレッドAがデータ取り出し完了 スレッドBがイベント待ちに入る。データがあるのにイベント待ちから戻れない となる恐れがない? (CSのEnter/Leaveは省きました) www.linux.or.jp/JM/html/glibc-linuxthreads/man3/pthread_cond_destroy.3.html の、 > 条件変数はいつでも mutex と結びつけられていなければならない。これは、あるスレッドが条件変数を > 待とうとしている時に、他のスレッドが、先のスレッドが実際に条件変数に対して待機するその直前に > 条件を送信する、という競合条件を避けるためである。 を参考にしました。
458 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:30:15 ] というわけで、producer-consumerのうまいコード例があればお願いします。
459 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:31:34 ] 投入データの個数をセマフォで管理しとけばいいんじゃないかな データ投入後→セマフォを1上げる データ取り出し前→セマフォを1下げる(データがない=セマフォが0の場合は投入される=1以上になるまでブロック)
460 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:35:29 ] >Mutexの開放とEvent待ちをアトミックに行うことができないから。 はいはい。SignalObjectAndWait, SignalObjectAndWait。
461 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:39:35 ] >>460 んー、この用途に使えるのか。サンクス。調べてみます。 >>459 最悪それでいこうとおもってます。けど460のでいけるならそれがベター。
462 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:40:44 ] というか、Producer-Consumerなら、スレッドプールつかって あとは知らぬの半兵衛を決め込めばいいような気がしてきたぞ。 Producer() { { CriticalSectionLock csl(cs); return if list.full? list.push( somethings ) QueueUserWorkItem( Consumer ); } } Consumer(){ { CriticalSectionLock csl(cs); workitem = pop(); QueueUserWorkItem(Producer); } SomeWork; }
463 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 01:41:59 ] >>462 そういうのもあるんですか。そっちも調べてみます。 ありがと。
464 名前:デフォルトの名無しさん [2008/01/27(日) 01:57:33 ] >>456 ブロードキャストしたい場合は
465 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:08:57 ] その場合は、根本から考え直しだよね。 APRみたいに、Manual Rese Eventを待つたびに、待ちスレッド変数をインクリメントして 起こされるとデクリメント。自分が最後に起こされたスレッドかどうかを判断して、 ResetEvent発行するとかさ。
466 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 02:11:42 ] manual resetにするわけか。めんどくさいね。
467 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 14:51:01 ] 結論:Windowsはクソ
468 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 15:00:27 ] 条件変数を作るとして、それに使うWindowsの同期オブジェクトはどれが軽くてお勧めか?
469 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 15:18:26 ] CriticalSectionにSignalObjectAndWaitできるの?
470 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 15:18:47 ] >>468 Vistaを使う
471 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 16:59:39 ] >>435 thread pool化した。8thread上げといてそれを、 pthread_cond_wait/signal/broadcast pthreaf_mutex_lock/unlock で、ぶん回した。 non thread時の倍ほどがのスピードが、漸くでた。 単純にctreate/joinだけだと、メチャメチャコストが高いのですね。 このときは、non thraed時の8倍ほど時間がかかった。
472 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 18:19:52 ] >>468-469 CSが使えないんだとしたらエラく遅くなるよな。 実際のところどうなのか教えてエロい人。
473 名前:472 mailto:sage [2008/01/27(日) 18:24:54 ] www.cs.wustl.edu/~schmidt/win32-cv-1.html の3章に実装例があった。 どれも大変な事になっているな。たぶん、pthread_cond_broadcast()を実現しようとしているからだと思うが。
474 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 20:08:28 ] VS2005、C++でWin32ウィンドウプログラムを作成しています。 キューの中身が空の間、スレッドを待機させたいのですが、while(que.empty()) { Sleep(0); } とすると、CPUはぶんまわされるわ、スレッド終了フラグも受け取れないわで困っています。 キューにデータが入った瞬間にスレッドが回りはじめ、かつ終了フラグも受け取るためにはどうすればよいのでしょうか? 初歩的な質問ですみませんがよろしくお願いします。
475 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 20:29:07 ] 釣り?
476 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 22:12:47 ] いえ、釣りではないのですが… もう少し調べてみます。 それでも分からなければ初心者スレに行きます。 スレ汚し失礼しました
477 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 22:51:27 ] とりあえず、セマフォを使ってみよう。
478 名前:デフォルトの名無しさん mailto:sage [2008/01/27(日) 22:54:49 ] というか、今までの話題がまさにそのProducer/Consumerパターンについてなわけだが
479 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 00:08:21 ] >>449- .NETならこれ msdn.microsoft.com/msdnmag/issues/07/05/CLRInsideOut/default.aspx?loc=jp Vistaならこの記事がおすすめ。 msdn.microsoft.com/msdnmag/issues/07/06/Concurrency/default.aspx?loc=jp
480 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 00:09:22 ] >>479 C++でXPなんです・・
481 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 01:08:54 ] つうか、セマフォ使えや、カス
482 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 01:20:54 ] メータードセクションだろ普通
483 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 01:21:26 ] >>481 誰にいってんの?
484 名前:デフォルトの名無しさん [2008/01/28(月) 01:23:40 ] >>482 へぇ。そんなのあるんだ。プロセス間でも使えて、一定回数はカーネルに落ちないでspin?
485 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 02:31:00 ] 全部ホシュするなら、全部ヤッパ明渡せヤゴラ、でOK
486 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 07:52:58 ] ?
487 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 09:51:29 ] VMwareでLinux上げてpthread使えば解決
488 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 10:42:06 ] queueに要素があるかは、>>477 ,>>481 の通りセマフォでやればいいんじゃない? 増減するリソースを管理するんだからちょうどいいでしょ。 フラグの変更はイベントにでもして一緒に待つか、queueに終了って言うなにかを投げ込めば?
489 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 18:01:56 ] Linux野郎なんでWindowsには全く疎い俺参上! Windowsの独自スレッドだけでpthreadはないの? あと、pthreadとWindowsスレッドを比較した利点・欠点 がまとめてあるHPとないでしょうか?
490 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 20:46:19 ] >>484 スピンで待たせるなら、プロセス内専用だけどWindowにもInitializeCriticalSectionAndSpinCountなんてものもあるよ。
491 名前:デフォルトの名無しさん mailto:sage [2008/01/28(月) 22:07:07 ] メータードセクションは、Windowsの話だけど・・・
492 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 06:27:19 ] CriticalSectionがspinなのはわかってるよ
493 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 06:34:26 ] >>489 Linuxにも疎そうだな
494 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 09:57:59 ] どうしてもpthreadがいいなら、pthreads for Win32があるでしょ。 以前mingwでつかってたよ。VCでも使えたはず。
495 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 12:58:59 ] 下のようなクラスを作って、Monitorでのロックと比較してみた。 EnterWithContextSwitchで、ロックがほとんどかち合わないで誤差の範囲で軽く、ロックが頻繁な場合だと 明らかに遅くなる。Enterは確実に遅い。 class SpinLock { volatile int _isEntered; public void Enter() { while (Interlocked.CompareExchange(ref _isEntered, 1, 0) != 0) { }} public void EnterWithContextSwitch() {while (Interlocked.CompareExchange(ref _isEntered, 1, 0) != 0) {Thread.Sleep(0);}} public void Exit() {_isEntered = 0;} } //試したのはこんな感じ 各スレッドで for (int i = 0; i < _loopCount; i++) { thp.LockDeleg(thp);//ここでLockして DoWork(_jobTime);//ここで指定時間処理して thp.UnLockDeleg(thp);//ここでUnlock } 対象のロックはmontor,SpinLockともども複数生成して、ロックするときにランダムでロック対象を決めるようにした。生成するロック数も多い場合、少ない場合色々試してみた。 環境はXP Sp2 C# .NET2.0 DualCoreのアスロン何たら。 テスト中はCPUを使い切る場合もあれば各CPUが70%ぐらいで推移する場合もあり。どちらのロックでそうなるかは不明。多分SpinLock。 参考URL msdn.microsoft.com/msdnmag/issues/05/10/MemoryModels/ 何か間違ってる?ついでにおまいらのマルチスレッドに関する考え方、使い方を教えてくれ。 教えてエロイ人
496 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 18:13:34 ] 何がしたいのこれ?
497 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 18:26:19 ] .netのモニターオブジェクトと自前スピンロックの性能評価?
498 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 18:42:28 ] 具体的に何を計りたいのかよくわからん。 ついでについては、ロックがかち合う可能性を下げるように設計する。
499 名前:495 mailto:sage [2008/01/29(火) 18:54:29 ] 違う回線よりすいません。 説明不足で申し訳ないです。 言われるとおり、自作スピンロックでどれだけロックが軽くなるかの調査です。 いくつかの記事で、SpinLockでのcpu消費の方が、コンテキスとスイッチより軽いと言っていたので試してみました。 結果が記事と逆になってしまったので自分のコードが何かおかしかったのかと。
500 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 19:10:11 ] スピンロックはマルチプロセッサじゃないと効果無いんじゃないか? スピンしてる間にロックが外れれば、カーネルに落ちなくて済むじゃん
501 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 19:27:06 ] >環境はXP Sp2 C# .NET2.0 DualCoreのアスロン何たら。 って書いてあるから、2つあるんでそ。
502 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 19:31:05 ] あ、ほんとだ。失敬失敬。
503 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 19:33:43 ] 単純なサンプルで重い、軽い、と早い、遅いを同列に語っても意味無いかと。 あとSleep(0)の分解能なんてろくに無いんだから いちいちロックされてるたびに呼んでたら無駄に待たされる。 ただ、一般的には、他の誰かが処理してるからCPU時間を明け渡してあげることで いち早くロックを取得できる可能性をあげる意味でSleepを使う Sleep(0)の分解能調べて見て、中のジョブがどれぐらい時間かかってるか 調べて見れば、あなたのいう軽いとか遅いとかがより深く理解できると思う。 Win32だったらCriticalSectionで一発だったんだが .netはLockかInterlockしか無いのかな
504 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 19:33:52 ] public void EnterWithContextSwitch() {while (Interlocked.CompareExchange(ref _isEntered, 1, 0) != 0) {Thread.Sleep(0);}} というか、これ "Sleep(0)" が原因でねーの。他にするタスクがないとき、CPU休まないじゃん。
505 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 21:06:30 ] .NETのロックは元々クリティカルセクションだよ。
506 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 21:15:59 ] 単純なスピンロックなんざそもそも間の処理が極めて短時間で 競合なんてまず滅多に起こらん場合にしか向かん。
507 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 21:27:30 ] どうもインタロック操作が極端に軽いと勘違いしてる奴や記事が多いな。 .NETなんて単純にロックでもそう大差はないのに。
508 名前:デフォルトの名無しさん mailto:sage [2008/01/29(火) 21:39:37 ] ああこれは件のMSDNの記事の事じゃないので念のため。
509 名前:495 mailto:sage [2008/01/29(火) 21:59:01 ] >>506 そのようだ。 >>507 極端に軽いと勘違いしてた。 今は反省している
510 名前:デフォルトの名無しさん mailto:sage [2008/01/30(水) 13:04:30 ] >>21 によれば、.netの機能をそのまま使えば良いんじゃないか?
511 名前:デフォルトの名無しさん mailto:sage [2008/01/30(水) 19:09:40 ] うんそう。 あえてスピンロックにするのはインタロック操作1回分までも節約したいとき。 2回→1回
512 名前:デフォルトの名無しさん [2008/02/03(日) 11:08:05 ] 環境visualstudio2005 vc++ _beginthreadexを使ってメインを合わせて合計3個と100ms毎の割り込みをさせてるんですが、 assert(0)が有効にならない場合があります。マルチスレッドで緊急にプログラムを停止させたい場合は どうすればいいんでしょうか?
513 名前:デフォルトの名無しさん mailto:sage [2008/02/03(日) 11:18:51 ] ExitProcess
514 名前:デフォルトの名無しさん mailto:sage [2008/02/03(日) 11:33:51 ] >>512 WaitoForSingleObjectとSetEventを使う。
515 名前:デフォルトの名無しさん mailto:sage [2008/02/03(日) 12:06:49 ] assert(0)
516 名前:デフォルトの名無しさん mailto:sage [2008/02/03(日) 17:58:20 ] >>514 Waito ?
517 名前:デフォルトの名無しさん mailto:sage [2008/02/03(日) 18:28:11 ] WaitoSinguruObujecuto と SinguruIvento
518 名前:SettoIvento ならわかるが... mailto:sage [2008/02/03(日) 21:12:20 ] SinguruIvento ?
519 名前:514 mailto:sage [2008/02/03(日) 21:19:11 ] ゆるしてっ!!
520 名前:デフォルトの名無しさん mailto:sage [2008/02/04(月) 19:47:15 ] >>512 俺を使え。全力でとめてやるぜ
521 名前:デフォルトの名無しさん mailto:sage [2008/02/08(金) 14:49:26 ] 生成したスレッドから、 ウィンドウハンドルを使用するマクロを使うためにはどうすればいいですかね?
522 名前:デフォルトの名無しさん mailto:sage [2008/02/08(金) 14:54:37 ] わかりやすい日本語でお願いします。
523 名前:デフォルトの名無しさん mailto:sage [2008/02/08(金) 18:17:55 ] >>521 ウインドウハンドルが欲しいのかな?
524 名前:デフォルトの名無しさん [2008/02/11(月) 23:34:04 ] Visual Studio.NET 2003で、Win32API、C++のプログラムをしてるんですが、 複数スレッド同時に、クラスのオブジェクトをnewしまくると、 ・HEAP[aaa.exe]: HEAP: Free Heap block 3c04d0 modified at 3c04e0 after it was freed ・0xC0000005: 場所 0xfeeefeee に書き込み中にアクセス違反が発生しました。 。 ・0xC0000005: 場所 0xfeeefeee を読み込み中にアクセス違反が発生しました。 。 などのエラーがでます。 何か回避方法はないでしょうか? newしてるのは同じクラスのオブジェクトですが、 static変数は持っておらず、グローバル変数も共用してません。 共用のものとしてはstatic関数を持ってますが、使ってはいません。
525 名前:デフォルトの名無しさん mailto:sage [2008/02/12(火) 00:22:37 ] > 何か回避方法はないでしょうか? バグを直す。
526 名前:デフォルトの名無しさん mailto:sage [2008/02/12(火) 00:41:03 ] ランタイムがシングルスレッド用になってんじゃね?
527 名前:524 mailto:sage [2008/02/12(火) 00:58:26 ] >>525 シンプルな以下のクラスでテストしてみたんですが、 やっぱり同じエラーが出ます。 class TestClass{ public: TestClass(); virtual ~TestClass(); }; TestClass::TestClass(){} TestClass::~TestClass(){} >>526 ランタイムってなんでしょうか? VCで設定するものですか?それとも実行する環境に依存するもの?
528 名前:デフォルトの名無しさん mailto:sage [2008/02/12(火) 01:01:02 ] クラスの定義よりも寧ろ、「newしまくる」方を晒せよ。
529 名前:524 mailto:sage [2008/02/12(火) 01:06:18 ] >>526 ありがとうございます! VCの設定で、 プロジェクトのプロパティ→C/C++→ランタイムライブラリを、 マルチスレッドデバッグにしたらエラーが出なくなりました。
530 名前:デフォルトの名無しさん mailto:sage [2008/02/12(火) 01:11:48 ] ヤレヤレ
531 名前:デフォルトの名無しさん mailto:sage [2008/02/12(火) 12:34:51 ] >>529 シングルスレッド用でコンパイルが通ったてことはCreatThreadを使ってるのかな?_beginthreadExを使ったほうがいいよ。
532 名前:524 mailto:sage [2008/02/13(水) 02:11:46 ] >>531 _beginthreadExは知りませんでした。 調べてみます。ありがとう。
533 名前:デフォルトの名無しさん mailto:sage [2008/02/13(水) 10:20:00 ] グローバル変数使う標準Cライブラリ(strtokとか)を使う場合、_beginthreadExじゃないとまずいことになる。 そうじゃないならCreateThreadでも特に問題なかったと思う。
534 名前:デフォルトの名無しさん mailto:sage [2008/02/13(水) 23:11:17 ] >>533 mallocやnewとか、VCランタイムのいろんなものがやばい。 コンパイラベンダでも無い限り、CreateThread使う必要なし。
535 名前:デフォルトの名無しさん mailto:sage [2008/02/14(木) 00:54:08 ] マルチプロセッサ環境でストアバッファのデータを反映させたい場合 pthreadだとmutex使えばいいんでしょうか?
536 名前:デフォルトの名無しさん mailto:sage [2008/02/14(木) 01:38:26 ] >>535 同期プリミティブの使用でフラッシュしてくれなかったら、どうにもならない。
537 名前:デフォルトの名無しさん [2008/02/14(木) 02:08:24 ] >>535 んー、volatileかな。
538 名前:デフォルトの名無しさん mailto:sage [2008/02/14(木) 13:03:57 ] メモリバリア
539 名前:535 mailto:sage [2008/02/14(木) 23:26:30 ] 恥のかきついでに。。。 フラッシュされるということはmutexのアンロック後に 他のスレッドから同期プリミティブを使用せずにメモリを参照しても mutexがアンロックされた時点までの操作は完了してると見なしていい この解釈は合ってるのかな
540 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 01:55:14 ] posixがそれを要求してる、って d.hatena.ne.jp/yupo5656/20040618/p2 ここらへんに書いてあった。
541 名前:535 mailto:sage [2008/02/15(金) 02:19:14 ] なるほど。 www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html#tag_04 ここにある関数を呼び出した時点でメモリが同期されるわけですね ありがとうございました
542 名前:デフォルトの名無しさん mailto:sage [2008/02/15(金) 11:02:56 ] >>539 mutexのアンロックで書き込み側プロセッサのキャッシュがメモリと同期されても、 それだけでは読み込み側プロセッサのキャッシュはメモリと同期されないのでは? 読み込み側にも同期プリミティブ(具体的にはmutexのロック)が必要なはず
543 名前:535 mailto:sage [2008/02/16(土) 15:34:51 ] >>540 の"同時アクセスさえ防いでおけばすべてうまく行く" というのを信用したんですが・・・どっちが正しい?
544 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 16:21:03 ] キャッシュと同期オブジェクトは別じゃないのか。
545 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 16:21:28 ] 同時アクセスを防ぐ=読み側もmutexなりでロックしにいく でも読み込みだけならロックいらないよね。volatile最強!
546 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 16:39:51 ] >>545 一応マジレスしておくと、volatileでは確実に読めることが保証されない。安全を期するならロックした方が楽。 # 理由については割愛。
547 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 17:41:24 ] CPUのマニュアル読むのが一番
548 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 17:42:24 ] >>543 読み込み側もmutexをロックしないと、同時アクセスを防げないじゃないか。 まだ書き込み側がmutexをアンロックする前かもしれないのに。
549 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 15:13:07 ] pthreadの、pthread_join()とsleep()の関係について質問します。 主系スレッドZにて、子スレッドa, b, cをpthread_create()により作成します。子スレッドa, b, cは一定時間経過後に処理を行います。一定時間経過するのを待機する場合、sleep()を使っています。 主系スレッドZでは、子スレッドa, b, cが終了するのを待つために、pthread_join()を使っています。しかし、子スレッドa, b, cがsleep()で待機しているときを、子スレッドが終了した時と勘違いしているようです。 現在では、子スレッドa, b, cが終了する前に、それぞれが主系スレッドZにsignalを送るようにしています。主系スレッドZでは、signalが来るまで待機としています。 最初にやっていた、pthread_join(), sleep()の組合せの方がスマートだと思うのですが、こちらの方法でうまくやるのは無理なのでしょうか?
550 名前:549【言語】【実行環境】【その他突起する事項】 mailto:sage [2008/02/17(日) 15:18:17 ] 環境を書き忘れていました。 【OS】debian/etch 【言語】C(pthread/posix) 【実行環境】 glibc2.3.6 gcc4.1.2 kernel 2.6.18-6-486 libpthread NPTL2.3.6
551 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 15:21:59 ] 突起フイタ
552 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 15:50:00 ] >主系スレッドZでは、子スレッドa, b, cが終了するのを待つために、 >pthread_join()を使っています。しかし、子スレッドa, b, cがsleep()で待機しているときを、子スレッドが終了した時と勘違いしているようです。 コード晒してみてくれ
553 名前:549 mailto:sage [2008/02/17(日) 16:23:25 ] どうやら勘違いだったようです。 真の原因は、Zでログファイル用に fp_glb=fopen("Z.log","w"); として、fpを持っているのですが、子スレッドが、 fprintf(fp_glb, "log write thread name [a]\n"); として、共通のログファイルに書き込みを行おうすると、死んでいるようでした。子スレッドでは、書き込む前に排他ロックを行っているのですが、主系スレッドでは行っていないことが原因だと思っています。
554 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 16:24:12 ] 無茶苦茶だな。
555 名前:デフォルトの名無しさん [2008/02/19(火) 09:12:29 ] VC++にpthreadはないのでしょうか?
556 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 11:47:28 ] >>555 >>494
557 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 19:33:15 ] 自分から終了することもあるし、外部から終了通知を受け取ることもある ようなスレッド関数について質問です。 こういう場合、(スレッド関数はすでに終了してるぞ!)フラグや (外部から終了通知が出されたぞ!)的な何かはいったいどうやって実装していますか? 自分はいつも bool isActive = false; bool IsThreadActive() { lock {return isActive} } void SetThreadActive(bool flag) { lock {isActive = flag; } } void ThreadFunc() { SetThreadActive(true); try { while (IsThreadActive()) { ... いろんな処理 } } catch(...) { SetThreadActive(false); throw; } } 的なやり方でやってしまっているのですが、 これって正しいのでしょうか? また、もしあればもっといい方法を教えていただけると助かります。
558 名前:557 mailto:sage [2008/02/20(水) 19:36:19 ] 書き忘れました while (IsThreadActive()) { ... いろんな処理 } の内部から breakで抜けることもあります。 (SetThreadActive(false)も付け足してください)
559 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 19:41:56 ] 終了要求フラグとすでに終了してるぞフラグは別にした方がいいんじゃないかな すでに終了してるぞフラグが要るかどうか(何に使うのか)にもよるような
560 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 20:03:24 ] スレッドでいくつかの処理を行いたいのですが、 その処理の内容が 1、実はまったくスレッドが必要にならない場合がある 2、処理の行われる間隔が長いので、 続く処理が無いようならとりあえずスレッドを終了させたい というもので、ある処理のリクエストが入ったとき、 *スレッドが稼動していればそのままリクエストを追加 *稼動していなければ新たにスレッドを起動して処理を開始 *終了要求が入ったらすべてのリクエストを破棄&スレッドを終了 ということがしたいのです。
561 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 20:13:33 ] スレッドを終了する要因がメイン側からの要求だけなら、 スレッドが生きてるかどうかはメイン側が完全に把握してるはずなので、 子スレッド側から「すでに終了してるぞ」フラグを操作する必要はないはず
562 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 20:23:14 ] >>561 スレッドを終了させる要因には、メイン側からの通知もそうですが、 子スレッド内での例外や、自殺も含まれます。 結局、これはフラグで操作するしかないのでしょうか? というのも、「スレッドをフラグで操るなんて危なすぎ」みたいな話を聞いたことがあるので・・・ それにconditionとか、なんとなくかっちょいい機能を使いたいような気もします
563 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 20:30:57 ] >>561 すいません。分かりにくかったですね。これも追加してください *リクエストが無ければ、とりあえずスレッドを終了(再びリクエストが来たら再度起動)
564 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 20:55:19 ] 例外で死ぬなら、残ったリクエストを誰かが引き継がなきゃいけないような・・・ キャッチできるなら再開して残りのリクエストを処理する方がいいんじゃないかな リクエストキューとスレッド生存フラグは単一のロックで操作しないとまずいことになると思う 終了要求フラグは別のロックでも構わないけど、一緒にしとくのが無難かと 親側 lock { リクエスト投入 if (スレッド生存==false) { 子スレッド起動; スレッド生存=true } } 子側 loop { lock { if (終了要求) { スレッド生存=false; return } リクエスト取り出し if (もうリクエストないよ) { スレッド生存=false; return } } try { リクエスト処理 } catch { エラーメッセージを吐くとか } } たぶんこんな感じ?
565 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 20:57:14 ] 終了してるかどうかはそのためのもの(WinならWaitForSingleObjectとか)で調べるでしょう。
566 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 21:08:10 ] >>565 スレッドが例外とかで突然死した場合はメイン側でWaitFor〜なりで捕まえて再起動するしかないけど、 リクエスト投入時の新スレッド起動判断をそれでやると、 その直前にリクエストがキューにないと判断したため自発的に終了しつつあるスレッドと入れ違いになる可能性が・・
567 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 21:25:45 ] >>564 おお、なるほど。そういう風にやればいいんですね。 >>557 だと、「いろいろな処理」中にisActiveがfalse、 かつリクエスト追加でフラグがtrueになるとスレッド二つになりますし、 タイミング的にスレッド消える危険もありますね。 それをテンプレにしていろいろ試してみたいと思います。 ありがとうございました。
568 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:14:25 ] 俺ならこんな構造にする。 ・リクエストを出すスレッドはイベントループを持つ。 ・作業スレッドはリクエストキューと終了要求フラグを見ながら愚直に仕事をする。 ・作業スレッドが処理を1つ済ませたり終了したりしたら、 1回だけ呼ばれるコールバックを要求元スレッドのイベントループに登録する。 ・コールバックは要求元スレッドで走り、処理結果やエラーを通知する。 問題は、イベント待ちで寝ているときに目を覚まさせる方法が 既成のイベントループに必ずしも用意されていないこと。
569 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 09:40:13 ] 毒を投げればいいだろ
570 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 09:48:43 ] 基本的にスレッドはブロッキング操作があるようなものを非同期で行わせるために俺は使ってるから, イベントループとか使えないんだよね
571 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 12:56:56 ] 一方、漏れは匙を投げた。
572 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 19:03:51 ] double pi=3.14159265358979823846; if((fp=fopen("PI.bin","wb"))==NULL) printf("\aファイルをオープンできません。\n"); else{ fwrite(&pi,sizeof(double),1,fp); fclose(fp); } C言語で↑のようにpiをバイナリファイルに書き込んで、 BZというバイナリエディタで開いたのですが”$-DT・ @”(文字部)と表示されました。 その後にfread関数でPI.binの内容をプログラム上で出力すると3.1415926……とさきほどの数字に限りなく近い数字できちんと表示されたのですが バイナリエディタで見ると変な文字に変わってしまうのは、何が原因なのでしょうか?これをバイナリファイルとして正しく見れる方法はあるのでしょうか。
573 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 19:04:04 ] ブルータス!お前もか!
574 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 19:07:45 ] >>572 スレタイと何か関係あった?
575 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 19:10:06 ] >>574 完全に誤爆です すいませんでしt
576 名前:デフォルトの名無しさん [2008/02/26(火) 01:43:14 ] >>572 原因はお前の頭が悪いこと。 そもそもスレ違い。
577 名前:デフォルトの名無しさん mailto:sage [2008/02/26(火) 04:30:54 ] 5日も前に誤爆だったと謝罪済みのレスに文句言う馬鹿って一体何考えてるの?
578 名前:デフォルトの名無しさん mailto:sage [2008/02/26(火) 10:36:12 ] 脊髄で書いてるのだろう
579 名前:デフォルトの名無しさん mailto:sage [2008/02/27(水) 17:15:56 ] 脊髄電脳化w
580 名前:デフォルトの名無しさん mailto:sage [2008/02/28(木) 00:56:57 ] マルチスレッド対応の ハッシュリストのソースコードとかある?
581 名前:デフォルトの名無しさん mailto:sage [2008/02/28(木) 12:32:38 ] ハッシュは速いのが売りなんだから、まるごとクリティカルセクションで包んでおけ
582 名前:デフォルトの名無しさん mailto:sage [2008/02/28(木) 12:51:50 ] >>580 Javaのjava.util.concurrent.ConcurrentHashMap
583 名前:デフォルトの名無しさん mailto:sage [2008/02/28(木) 13:19:30 ] javaならHighly Scalable JavaのNonBlockingHashMap等 ttp://sourceforge.net/projects/high-scale-lib
584 名前:デフォルトの名無しさん mailto:sage [2008/02/28(木) 16:02:03 ] >>581 意味ねーw
585 名前:デフォルトの名無しさん mailto:sage [2008/02/29(金) 23:39:30 ] 同期処理なんてしなくてよし。 すべては運任せ。 マルチスレッドの邪神様に任せておきなさい。
586 名前:デフォルトの名無しさん mailto:sage [2008/03/03(月) 11:34:48 ] コア1個ならなんとかなるさ、きっと
587 名前:デフォルトの名無しさん mailto:sage [2008/03/03(月) 21:36:55 ] ●5 コアは一個だが、HTだった
588 名前:デフォルトの名無しさん mailto:sage [2008/03/03(月) 23:09:15 ] HTといえば、マルチコアの場合は異なるコア同士が同じキャッシュラインに アクセスしない方がいいけど、HTの場合は逆になるの?
589 名前:デフォルトの名無しさん mailto:sage [2008/03/03(月) 23:49:44 ] マルチプロセッサ・マルチコア・HTで論理CPUが8個とかってどこのXEONだっけ?
590 名前:デフォルトの名無しさん mailto:sage [2008/03/04(火) 16:41:04 ] AMDのです
591 名前:デフォルトの名無しさん mailto:sage [2008/03/04(火) 22:30:10 ] >>588 キャッシュが共有の場合は、キャッシュラインが同じでもOK。そのほうが効率よい。 キャッシュが分かれている場合は、同じキャッシュラインへの書き込みは最悪になる。MESIプロトコルで具具ってみよう。
592 名前:デフォルトの名無しさん mailto:sage [2008/03/05(水) 13:50:16 ] journal.mycom.co.jp/articles/2008/03/02/isscc3/003.html HTMって性能出るのかな。。
593 名前:デフォルトの名無しさん mailto:sage [2008/03/05(水) 14:19:28 ] トランザクションメモリって、 JavaのAtomicReference#compareAndSetみたいなのじゃだめなの?
594 名前:デフォルトの名無しさん mailto:sage [2008/03/05(水) 16:58:48 ] 失敗したとき、その中でやったことは全部無しにしてくれるんだろうか? >>593 良い場合もあるけど、例えば、複数のHashMapとかをatomicに操作したい場合は面倒じゃない?
595 名前:デフォルトの名無しさん mailto:sage [2008/03/05(水) 23:18:48 ] マルチスレッドなくなってしまう。 今までがずっとCPUだと思っていたものは、実はスレッドなんで、。
596 名前:デフォルトの名無しさん [2008/03/06(木) 02:46:25 ] Windowsでの条件変数実装の話題蒸し返したいので、俺の調査結果を晒してみる。 apr -> 再帰mutex非サポートぽい?簡潔過ぎるし、他にもバグあるだろ絶対。 yaneSDK3rd::LockObject -> すごく分かりやすい実装。再帰ロックしてのwaitにバグあり。修正は簡単。 boost::condition -> 複雑。完璧なのか?タイムアウト監視にシステム時刻使ってるのが嫌。 自前のC++ライブラリ構築して使ってるが、 yaneSDK3rdベースの実装からboostベースに交換してみようと思って とりあえず、boost::xtime使ってる部分はGetTickCountに変えた。 システム時刻は某通信プロトコルでいつでも変更されてしまうので。 っつーか、clock()とかにもFILETIME使ってるのってどうなのよ・・・ boost実装に>>473 のような問題が無いか検証しようとしてるが、 こいつのアルゴリズムは結構複雑で手強そうだ・・・ 肝心のACEのソースはまだ読んでない。
597 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 02:19:24 ] 条件変数の用途って 生産者/消費者的な使い方がかなりの部分を占めると思うんだけど、違うかな? そういう用途のみに限れば、IOCP使えば充分なんじゃないのかね。 キューにデータがあるときはカーネルに行かないって言明されてるし。
598 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 02:15:16 ] 無知を承知で聞くけど、ユーザーモードに限って言えば 普通はCriticalSection一択じゃないの? CriticalSection自体がSpinCountの設定次第でカーネルモードにいかないようになってるから そのチューニングで大体の用途には間に合うと思うんだが。 VistaだとRead/Writeロックが実装されたから、そっち使ったほうが早いかもしれんけど。
599 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 18:32:59 ] Windowsはあまり知らないんだけど、Enter/Leaveしか出来ないの?
600 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 19:25:08 ] TryLock もバージョンが↓でなければできる
601 名前:デフォルトの名無しさん mailto:sage [2008/03/16(日) 09:31:31 ] VC++Windowsアプリの質問です。 メッセージループを1つのスレッドに隔離しようと思うのですが、 PostQuitMessage(0)を別スレッドから単純に呼び出しても安全でしょうか? HWND g_hWnd BOOL g_Active; // g_Activeをクリティカルセクション内でやり取り BOOL fGetActive(); VOID fSetActive(BOOL isActive); INT WINAPI WinMain(...){ fSetActive(TRUE); g_hWnd = (ウインドウハンドル作成); メッセージループ用スレッド生成 while( fGetActive() ){ if(...) PostQuitMessage(0); } メッセージループ用スレッド後処理 return 0; } UINT WINAPI MessageLoop(...){ MSG msg; msg.hwnd = g_hWnd; while (GetMessage(&msg, NULL, 0, 0) > 0){ ... } fSetActive(FALSE); return 0; }
602 名前:デフォルトの名無しさん mailto:sage [2008/03/16(日) 11:40:27 ] サブスレッドからアプリケーションを直接終了させる設計は変じゃないか。 メインスレッドに何らかのメッセージを送って、メインスレッドからアプリケーションを終了すればよいじゃない。 面倒なら、少々強引だが、PostThreadMessageでメインスレッドに 直接WM_QUITを送りつけるのも。あまりお勧めしないが。
603 名前:デフォルトの名無しさん mailto:sage [2008/03/16(日) 12:57:27 ] ウィンドウはそれを作ったスレッドに結びついているよ
604 名前:デフォルトの名無しさん mailto:sage [2008/03/16(日) 13:10:12 ] >>601 PostQuitMessageを別スレッドから呼び出すことは問題ないけど、 メッセージは、ウィンドウの作成元のスレッドにしか来ないよ 別スレッドでGetMessageしたかったら、そっち側でCreateWindowしないとだめ
605 名前:604 mailto:sage [2008/03/16(日) 13:11:34 ] >PostQuitMessageを別スレッドから呼び出すことは問題ないけど、 って、ウソでした、カレントスレッドにWM_QUITを送るだけか PostThreadMessageで相手スレッドにWM_QUITを送ればいいかも
606 名前:デフォルトの名無しさん mailto:sage [2008/03/16(日) 14:31:10 ] >>602-605 ありがとうございます。 MSG構造体へメッセージを送る際のデッドロックが心配でした。 >>602 >サブスレッドからアプリケーションを直接終了させる設計は変じゃないか。 ウインドウモードだと×からも終了させる場合があるのと、 メインスレッドのID取得が難しそうなので変えられなそうです。
607 名前:デフォルトの名無しさん mailto:sage [2008/03/16(日) 22:42:23 ] >メインスレッドのID取得 プログラム開始時にメインスレッドから GetCurrentThreadId を呼んで、 メインスレッドのIDが取得して、それをグローバル変数にでも入れておけば良いかも。 それがいやなら、メインスレッドにくくりついている非表示ウィンドウを一つ作っておいて、 そこに向かって PostMessage して、メインスレッドにメッセージをポストするのも手。 windowsではよくある話。
608 名前:601、606 mailto:sage [2008/03/17(月) 15:08:05 ] もう一つ質問させてください。 メインスレッドがウィンドウを持ち、GetMessageのループをしていてかつ、 サブスレッドがメインスレッドのウィンドウにDirect3Dで描画している場合、 GetMessageとDirect3DがHWNDへのアクセス権をもめてクラッシュしますか?
609 名前:デフォルトの名無しさん mailto:sage [2008/03/17(月) 16:22:56 ] swapchainでググれ
610 名前:デフォルトの名無しさん mailto:sage [2008/03/17(月) 17:00:28 ] サブスレッドでバックバッファに書き込んだ後、 メインスレッドにバッファを転送するべきという意味ですか? うーん……
611 名前:デフォルトの名無しさん mailto:sage [2008/03/17(月) 21:18:56 ] >>608 クラッシュしませんよ。 ただ、例外があって、ディバイスをリセットするときだけはディバイスを作成したスレッドからリセットを コールしてあげないといけないからその点は注意。 メインスレッドでディバイスを作成した場合は、サブスレッドからはリセットは出来ない。 なので、もし、サブスレッドからディバイスをリセットする場合は、 まず、適当な自作ウィンドウメッセージをサブスレッドからメインスレッドのウィンドウに投げて、 メインスレッドのウィンドウがそれを拾ったらメインスレッド側から ディバイスをリセットする。
612 名前:デフォルトの名無しさん mailto:sage [2008/03/18(火) 21:47:01 ] Linux 2.6.21です sigwait()しているスレッドに他のスレッドからpthread_cancel()を実行してもスレッドがキャンセルされません sigwait()はキャンセルポイントのはずなのになぜ、と困惑しています うちの環境のみなんでしょうか もしくはLinuxの仕様?
613 名前:612 mailto:sage [2008/03/19(水) 07:24:50 ] すいません、自分の勘違いでした
614 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 19:48:12 ] すいません。教えてください。 linux 2.6.20でpthreadです。 sched_get_priority_minとsched_get_priority_maxで優先度の 最大値と最小値を得たところ両方0でした。 これは優先度を選択できないということでしょうか。 優先度の最大値、最小値を得るのに使った引数は sched_getscheduler(getpid())で値は0でした。 よろしくおねがいします。 あ、あと書き忘れましたがlttng0.9.0のパッチを当ててます。
615 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 20:06:05 ] >>614 www.linux.or.jp/JM/html/LDP_man-pages/man2/sched_get_priority_max.2.html >Linux では SCHED_FIFO と SCHED_RR では 1 から 99 の範囲の静的プライオリティーを持ち、 >SCHED_OTHER と SCHED_BATCH ではプライオリティとして 0 を持つ。
616 名前:614 mailto:sage [2008/03/25(火) 21:04:25 ] ありがとうございます。 優先度を指定しよう思ったらSCHED_FIFOかSCHED_RRにしろということですね。 考えて見ます。
617 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 02:52:53 ] RTの付いたカーネルじゃないとダメじゃなかったっけ?
618 名前:デフォルトの名無しさん mailto:sage [2008/03/31(月) 00:04:13 ] Numaで確保した共有メモリ内に pthread mutext仕込むと Numaで共有しているマシン間で 排他取れるの?
619 名前:デフォルトの名無しさん mailto:sage [2008/03/31(月) 13:08:46 ] 出来ないの?
620 名前:デフォルトの名無しさん mailto:sage [2008/03/31(月) 22:36:00 ] 教えてくれよw
621 名前:デフォルトの名無しさん mailto:sage [2008/04/01(火) 07:07:46 ] POSIX準拠なら取れないとおかしいという結論になるはず。 「NUMAで確保したの共有メモリ」がPOSIX準拠かどうかまでは知ったこっちゃねぇ。
622 名前:デフォルトの名無しさん mailto:sage [2008/04/01(火) 16:27:39 ] もし出来ないなら、アドレス空間が共有できてもうれしくないと思うんだが。 割と普通なOpteron複数搭載機ではまる人が続出しそう。
623 名前:デフォルトの名無しさん mailto:sage [2008/04/09(水) 23:10:05 ] docs.sun.com/app/docs/doc/819-0390/6n2qp46ei?a=view この関数ってなんか役に立つの?
624 名前:デフォルトの名無しさん mailto:sage [2008/04/10(木) 00:11:50 ] ??
625 名前:デフォルトの名無しさん mailto:sage [2008/04/10(木) 00:19:17 ] >>623 リード側と書き込み側の間でブロックしにくくなるんじゃないかな?
626 名前:デフォルトの名無しさん mailto:sage [2008/04/10(木) 00:37:03 ] >>625 じゃあmutexでおk?
627 名前:デフォルトの名無しさん mailto:sage [2008/04/10(木) 05:29:38 ] ??
628 名前:デフォルトの名無しさん mailto:sage [2008/04/10(木) 09:01:57 ] read同士でblockしない点が有用。
629 名前:デフォルトの名無しさん mailto:sage [2008/04/10(木) 10:00:18 ] あるデータAをRWロックでブロックしてるとする スレッド1がAを読み込もうとしてるときに・・・ スレッド2がAを読み込むことがある スレッド3がAを書き込むことがある となっている2つの場合を考える もしスレッド1と2のみであれば、Aの値は不変のはずだから 1が処理中でも2は処理できる。 つまりRead同士ではブロックする必要がない しかし、1と2が処理中に3が処理しようとするとおかしくなる。 だから読み込み同士ではブロックないが 書き込みはブロックしないといけない。 これがReadロック。 逆に、3が動いているときに、1と2が読み込もうとしている場合は 3が終わるまでは1も2も読み込んではいけない。 スレッド4が書き込みをしようとしてたとして、これも当然ブロックしないといけない。 つまり排他処理するのがWriteロック。 これをMutexに置き換えると、Read同士でブロックしてしまう可能性があるので その頻度によってパフォーマンスが落ちることが考えられる。 しかし、とりあえず動かすことが重要であれば、置き換えるだけでも動く。
630 名前:デフォルトの名無しさん mailto:sage [2008/04/12(土) 12:43:28 ] マルチスレッドで仕事量分割するための 手法説明している本ってないっすか?
631 名前:デフォルトの名無しさん mailto:sage [2008/04/12(土) 15:24:51 ] VC6でマルチスレッドのアプリ作ってるんだがトラウマになりそうだ
632 名前:デフォルトの名無しさん mailto:sage [2008/04/12(土) 22:27:49 ] マルチスレッド間で カスタムメモリアロケタ君を 書きたいけど基本的なロジックとか みんな何参考にしてるの?
633 名前:デフォルトの名無しさん [2008/04/13(日) 23:00:37 ] すみません。 デバッグ中に、CPU帯域を独占してるスレッドを特定したいのですが。 なにかいい方法はありませんか? 開発環境はVisualStudio2005で言語はVC++です。
634 名前:デフォルトの名無しさん mailto:sage [2008/04/14(月) 00:02:22 ] パフォーマンスモニタでスレッドIDごとの負荷率が出る。 スレッドIDはデバッガで一時停止のスレッドで見られる
635 名前:デフォルトの名無しさん mailto:sage [2008/04/14(月) 00:17:59 ] >>634 ありがとうございます。 特定できました。
636 名前:デフォルトの名無しさん mailto:sage [2008/04/18(金) 07:54:17 ] >>635 特定しました。
637 名前:デフォルトの名無しさん mailto:sage [2008/04/18(金) 14:08:38 ] 特定しますた
638 名前:デフォルトの名無しさん mailto:sage [2008/04/18(金) 22:40:16 ] lock-freeアルゴリズムの 検証方法教えてくれよ どうやって正当性保障するんだよw あれ難しすぎだ
639 名前:デフォルトの名無しさん mailto:sage [2008/04/20(日) 18:56:56 ] SPINみたいなのを使うんだろうか?
640 名前:デフォルトの名無しさん mailto:sage [2008/04/20(日) 23:36:09 ] volatileで十分
641 名前:デフォルトの名無しさん mailto:sage [2008/04/21(月) 00:52:23 ] 原論文に検証あるだろ?
642 名前:デフォルトの名無しさん mailto:sage [2008/04/21(月) 21:53:58 ] それが理解できないから、易しく解説して って言う話じゃないのかな。
643 名前:デフォルトの名無しさん mailto:sage [2008/04/21(月) 22:43:36 ] 数式での検証と 実装の検証は違うと思うのは俺だけw? 俺は頭が悪いんだろうなw
644 名前:デフォルトの名無しさん mailto:sage [2008/04/21(月) 23:37:15 ] うん、頭が悪い。 「プログラムの正しさの証明」って言われて、 この証明が数学で言う証明のことだと理解できないタイプ。
645 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 07:35:55 ] 実用性ない数式出されてもなぁ 後から付帯条件つきまくる数式 出されてもなぁ
646 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 09:36:27 ] マジで頭悪そう
647 名前:デフォルトの名無しさん mailto:sage [2008/04/22(火) 22:16:26 ] ここも過疎ってるよなぁw
648 名前:デフォルトの名無しさん [2008/04/23(水) 08:00:42 ] 一覧に無いからだと思うあげ!
649 名前:デフォルトの名無しさん [2008/05/02(金) 17:43:24 ] 自作板にいるキチガイです。シングルスレッドで作成されてるソフトが カーネルによってマルチコアにスレッド(タスクのことか?)が分散されると申しております。 このIDだけの発言では分かりにくいが、このスレにはシングルスレッドでもマルチコアのほうが早いと のたまわってるキチガイがいます。 まだまだシングルCPUで頑張る人集合 pc11.2ch.net/test/read.cgi/jisaku/1169829748/ 800 Socket774 sage New! 2008/05/02(金) 08:31:32 ID:Aaj/7HlH このスレのシングルコアユーザーは未だにWindows3.1を使ってるようだw 801 Socket774 sage New! 2008/05/02(金) 08:32:49 ID:Aaj/7HlH プログラムのスレッドと CPUが処理する単位のスレッドは 意味が違うw 802 Socket774 sage New! 2008/05/02(金) 08:42:42 ID:Aaj/7HlH プログラムのスレッドはカーネルによってさらに細分化される 与えられたCPUタイムによってそれを1つづつ実行していく 大まかに2ブロックに分割されたとしよう 1コアが1ブロックを実行してCPU使用権が終了する その時に2コアが暇をしてるので2ブロックに即座に使用権が渡される つまり単純に2倍の処理性能になる 806 Socket774 sage New! 2008/05/02(金) 10:52:29 ID:Aaj/7HlH いやだからマルチスレッドOSって時点で 実際のCPU利用率は半分以下なんだよ どんだけがんばってもそうなの シングルコアだったら100%使えるとかないからw コアが2になるとより100%に近い状態になるわけ 一般に1.8倍だと言われる MS-DOSやWindows3.1を使ってる人はシングルコアのが早いかもねwww 807 Socket774 sage New! 2008/05/02(金) 10:57:04 ID:Aaj/7HlH >>803 ベンチマークのような単純処理の繰り返しではスレッドの細分化はほとんど行われない ゲームみたいな大きなスレッドになると実際に4倍近くの性能を発揮する
650 名前:デフォルトの名無しさん mailto:sage [2008/05/02(金) 17:51:33 ] >>649 頭のおかしな人というのはある程度の確率で常にあらわれるものであって、 そういう人がいるのはおかしいとか、説明して頭をよくしてあげよう等の考えは 全くの無駄だと思う。中身の入って無い枝豆同様ハズレとして無視するよりない。 いらいらする気持はわかるけどね。
651 名前:デフォルトの名無しさん mailto:sage [2008/05/02(金) 17:52:33 ] コピペ君に応答する奴も馬鹿だな、まで読んだ。
652 名前:デフォルトの名無しさん mailto:sage [2008/05/02(金) 19:14:41 ] osのタスク切り替え戦略によってはそうなるかもしれないけど、 普通は強制的な一定タイムスライスじゃないよね。 システムコール待つのにビジーウェイトでもしてると思ってんのか。
653 名前:デフォルトの名無しさん mailto:sage [2008/05/02(金) 20:14:27 ] ほかのタスクや割り込み処理に割り込まれる可能性が減る(ほかのCPUに割り振られる)から 「遅くなりにくい」ということはいえるが 速くなることはないだろうなあ。 って件のスレで当人書いてるじゃん
654 名前:デフォルトの名無しさん mailto:sage [2008/05/02(金) 21:56:31 ] 1coreの時にOS側のタスクによるオーバヘッドが1%程度あったとすると 2coreならアプリの実行時間が1%短くなる程度なら有り得る
655 名前:デフォルトの名無しさん mailto:sage [2008/05/03(土) 06:58:19 ] ゲームでならDirectSoundは別スレッドで動いてるので もうちょっと効果あるかもね。
656 名前:デフォルトの名無しさん mailto:sage [2008/05/03(土) 08:29:25 ] 例えばX11だと描画はサーバプロセスが行なうから結構効果がありますね。 でもそれをシングルスレッドアプリが速くなると言ってしまうとちょっと違うと思いますが。
657 名前:デフォルトの名無しさん mailto:sage [2008/05/03(土) 08:33:56 ] よっぽど単純なプログラムでもない限り 完全なシングルスレッドなんてあり得ないんですけどねw
658 名前:デフォルトの名無しさん mailto:sage [2008/05/03(土) 08:40:56 ] たとえばEXCELで 再計算処理が行われてる時にメニューを実行すると 再計算、描画、メニューの3つのスレッドが形成される
659 名前:デフォルトの名無しさん mailto:sage [2008/05/03(土) 08:47:38 ] ビス太のユーザーランドスレッドの方針を分かって話してるの?
660 名前:デフォルトの名無しさん mailto:sage [2008/05/03(土) 12:26:31 ] スレッドプールのはなし?
661 名前:デフォルトの名無しさん mailto:sage [2008/05/03(土) 15:17:42 ] >>658 スレッドが生成されるかどうかと 並行実行するかどうかは別だぞ
662 名前:デフォルトの名無しさん mailto:sage [2008/05/03(土) 18:15:41 ] OpenMP中で使ってるとか そんなんじゃねーのw
663 名前:デフォルトの名無しさん mailto:sage [2008/05/03(土) 19:22:28 ] >>661 XPでは平行実行してるが?
664 名前:デフォルトの名無しさん mailto:sage [2008/05/03(土) 19:59:25 ] >>663 させるかどうか、だ
665 名前:デフォルトの名無しさん mailto:sage [2008/05/03(土) 23:51:43 ] シングルスレッドでコンパイルするやつはいないだろw
666 名前:デフォルトの名無しさん mailto:sage [2008/05/04(日) 00:40:42 ] それまでの話の流れとは関係ないが 「マルチスレッド対応ライブラリを使用する」と 「マルチスレッドで動作するプログラムにする」は全く違うのだが まさかとは思うが、>>665 はそういう意味じゃないよな? 当然、「コンパイラをマルチスレッドで動作させる」だよね? 一応触れておくと Win32で普通にGUIプログラムを作る場合、明示的にスレッド関連の操作をしない限り マルチスレッドで動くことは無い。 何故なら、メッセージキューが1スレッドに1つ作られるので そこからのイベントで処理を記述する書き方だと、1スレッドにしかならないから。 (イベントハンドラでスレッド操作をすれば当然マルチスレッドも可能) もちろん、カーネル内の処理(割り込み等)は別。
667 名前:デフォルトの名無しさん mailto:sage [2008/05/04(日) 00:59:30 ] そういえば、Win9xのWinsock2の非同期処理は 内部的にスレッド作って擬似動作させてたんだっけ。 忘れてた。
668 名前:デフォルトの名無しさん mailto:sage [2008/05/04(日) 01:14:13 ] >>666 メッセージキューも明示的に作る(作らせる)ものであって スレッド作成=メッセージキュー作成じゃないよ。
669 名前:デフォルトの名無しさん mailto:sage [2008/05/04(日) 12:10:33 ] > メッセージキューも明示的に作る(作らせる)ものであって 具体的にどうやって作るの?
670 名前:デフォルトの名無しさん mailto:sage [2008/05/04(日) 12:39:33 ] MSDNのPostThreadMessageの所に書いてあるな
671 名前:まあ、明示的がどうかは人によって違うと思うが... mailto:sage [2008/05/04(日) 16:07:57 ] これのことかな... > その後、ポスト先のスレッドで、 > PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE) を呼び出し、 > このスレッド用のメッセージキューを強制的に作成します。 でもこれって、 > スレッドが Win32 のユーザー関数または GDI 関数のいずれかを最初に > 呼び出した時点で、システムはそのスレッドのメッセージキューを作成 > します。 ってことだよね。 あまり「明示的」とは思えないんだが...。
672 名前:デフォルトの名無しさん mailto:sage [2008/05/04(日) 17:10:13 ] 風が吹いたら桶屋が儲かるくらい暗黙的でなければ明示的
673 名前:デフォルトの名無しさん mailto:sage [2008/05/04(日) 22:53:30 ] いや別にメッセージループに入ったからといって CPUを最後まで占有出来るわけじゃないのだ 途中で強制的に割り込まれる そうすると他のループに権利が渡されるだけだな マルチスレッドでコンパイルすると各メッセージループは完全に独立したスレッドになる だから既存のアプリもほとんどはデュアルコアの恩恵がある
674 名前:デフォルトの名無しさん mailto:sage [2008/05/04(日) 23:11:24 ] おまえはそんなにメッセージループを作っているのか? 大多数のアプリはWinMainの中のGetMessage1つだけだと思うが
675 名前:デフォルトの名無しさん mailto:sage [2008/05/04(日) 23:12:03 ] それと、「マルチスレッドでコンパイルする」の意味を具体的に説明しろよ
676 名前:デフォルトの名無しさん mailto:sage [2008/05/04(日) 23:14:14 ] 上の方は、プリエンプティブマルチタスクの解説で、4行目の 「他のループ」=「他のプロセスのメッセージループ」なのかなー と思って読んでいたが >マルチスレッドでコンパイルすると各メッセージループは完全に独立したスレッドになる え?
677 名前:デフォルトの名無しさん mailto:sage [2008/05/05(月) 00:56:45 ] ちょっぴりエスパー能力を発揮して解読してみた。 普通、「メッセージループ」と言うと while (GetMessage()) { ... } の部分のことを指すと思うのだが おそらくこのヒトは、DispatchMessageで間接的に呼ばれるルーチン、 大抵は「WndProcの呼び出し1回」のことを 「メッセージループ」と呼んでいるような気がする。
678 名前:デフォルトの名無しさん mailto:sage [2008/05/05(月) 01:18:24 ] だとしてもウインドウプロシージャがマルチスレッドで 並列実行されたりはしないと思うが。
679 名前:デフォルトの名無しさん mailto:sage [2008/05/05(月) 01:48:05 ] もちろんその通り。 大丈夫、基本的な仕組みを理解してないのは、多分一人だけだから。
680 名前:デフォルトの名無しさん mailto:sage [2008/05/05(月) 03:39:24 ] え? そうなん? メッセージループをマルチスレッドでコンパイルしたら 完全にプリエンプティブなマルチコアになるでしょ
681 名前:デフォルトの名無しさん mailto:sage [2008/05/05(月) 05:18:58 ] だからその「マルチスレッドでコンパイル」って、何をどうすることなの?
682 名前:デフォルトの名無しさん mailto:sage [2008/05/05(月) 05:34:27 ] 一応、>>666 の前半部に、候補としていくつか挙げてあるけど ・マルチスレッドライブラリを使用する(コンパイラオプションを設定) ・マルチスレッドで動作するようにソースコードを書き換えてコンパイルし直す ・コンパイル時にコンパイラがマルチスレッドで動作するオプションを使う(対応しているもののみ) ・その他 ところで、「プリエンプティブなマルチコアになる」って何? 「マルチスレッドでコンパイルする」「メッセージループがスレッドになる」に続いて またまた第三者からは理解不能な言葉が出て来てるんですけど。
683 名前:デフォルトの名無しさん mailto:sage [2008/05/05(月) 05:37:36 ] >>680 これは釣りだろ
684 名前:デフォルトの名無しさん mailto:sage [2008/05/05(月) 06:45:01 ] 「マルチスレッドでコンパイルする」 そういえばVS2005から並行コンパイルができるようになったけど そのことかな。
685 名前:デフォルトの名無しさん mailto:sage [2008/05/05(月) 08:03:25 ] >>683 知ってる単語を並べただけと言う疑惑も捨てがたい。(w
686 名前:デフォルトの名無しさん mailto:sage [2008/05/05(月) 10:57:32 ] データを完全にシーケンシャルに 処理する必要があるのに スレッドの接続形態が 1-N-1って場合って どんな利点があるの?キュー作っても処理遅くなるだけじゃね?
687 名前:デフォルトの名無しさん mailto:sage [2008/05/05(月) 11:26:27 ] メッセージの元になるイベントは、システム全体に対して非同期に起こるんだよ。 おまいのアプリ上だけじゃないし、処理終了を待って定期的に起こるわけでもない。
688 名前:デフォルトの名無しさん mailto:sage [2008/05/05(月) 14:20:25 ] マルチスレッドでコンパイルする=MTsafeにするだろう
689 名前:デフォルトの名無しさん mailto:sage [2008/05/05(月) 15:24:34 ] >>686 ここの人には「完全にシーケンシャル」の意味するところがわからないから、 その形態作った奴に聞いてみればいいんじゃね。
690 名前:デフォルトの名無しさん mailto:sage [2008/05/05(月) 17:14:57 ] よくわからないけど、入力1、処理N、出力1みたいな感じだとすると、 最後の1を遊ばせないためには良いんじゃないかという気がする。 まあ何やるか次第だけど。
691 名前:デフォルトの名無しさん mailto:sage [2008/05/05(月) 17:16:08 ] >>690 でもめちゃくちゃ排他制御かからないかなぁ? 常にシーケンシャルってことは前のデータ待って 処理しないといけないってことだろうし
692 名前:デフォルトの名無しさん mailto:sage [2008/05/07(水) 11:17:48 ] コンパイラオプションのシングルとMTが具体的に何をしてるのかは知らないが MTにした時に各イベントは完全に非同期で発生する 並列実行してるのだと思ってるのだが違うのか?
693 名前:デフォルトの名無しさん mailto:sage [2008/05/07(水) 11:46:10 ] いいえ。イベント発生は非同期ですが、受信が並列に行われる保証はありません。 # つーか、並列実行できるくらいならイベント機構はもっと簡略化できるわけで。
694 名前:デフォルトの名無しさん mailto:sage [2008/05/07(水) 13:47:11 ] >コンパイラオプションのシングルとMTが具体的に何をしてるのかは知らないが コンパイラのヘルプ読めよ・・・
695 名前:デフォルトの名無しさん mailto:sage [2008/05/07(水) 17:24:03 ] マルチスレッドでコンパイルといえばマルチスレッド実行されるのが当然だろ 何言ってるんだか
696 名前:デフォルトの名無しさん mailto:sage [2008/05/07(水) 21:18:32 ] ・マルチスレッド (対応のコンパイラ) でコンパイルといえば (コンパイラが) マルチスレッド実行... ・マルチスレッド (オプションをつけた状態) でコンパイルといえば (生成されたプログラムが) マルチスレッド実行... 日本語難しいアルネ。
697 名前:デフォルトの名無しさん mailto:sage [2008/05/07(水) 22:05:44 ] 最近のコンパイラはマルチスレッドで動作するプログラムを勝手に生成してくれるの?
698 名前:デフォルトの名無しさん mailto:sage [2008/05/07(水) 22:07:56 ] MT対応ライブラリをリンクするだけじゃね OpenMPとか一応あるけど明示的にディレクティブを書かないといけないし
699 名前:デフォルトの名無しさん mailto:sage [2008/05/07(水) 22:13:13 ] それはライブラリの使い方次第だろう。 MT-safeになるだけっていうのとはまた違うし。 なんかレベルがよく分からない抽象的な話しかないのは気のせいか。
700 名前:デフォルトの名無しさん mailto:sage [2008/05/07(水) 22:27:00 ] >>697 コンパイラ自体は何もしないけど MFCとかのフレームワークがするんでしょ
701 名前:デフォルトの名無しさん mailto:sage [2008/05/07(水) 22:32:49 ] 私はいつものようにMFCでプログラムを組んでいた 当然のごとくMTをコンパイラオプションに指定した ある日、子ウィンドウから親ウィンドウにある関数を実行する必要性が出てきた 私はPostMessageでオリジナルのイベントを実装することを思いついた そこには処理Aと処理Bという2つの関数が存在した 処理Bは処理Aの結果を利用するものである 処理B単体で実行する場合もあるのでこの2つは独立していた 私は当然のごとく各イベントはシーケンスに処理させるのだと思い込んでいた メッセージA、メッセージBと順番に親ウィンドウに送信する するとどうだろうか プログラムは例外エラーを発生させて画面から消えるではないか 私は挙動を調べるべく調査に乗り出した そしてついにその原因を突き止めた この2つの処理は同時に実行されている
702 名前:デフォルトの名無しさん mailto:sage [2008/05/07(水) 22:42:19 ] 非同期のPostMessageじゃなくて同期のSendMessageだったっけ、そういうのなかった? winapiから遠ざかりすぎてワスレタ。非同期メッセージ通信なのだから、 >各イベントはシーケンスに処理させる って前提は、キューに入れられた順番はあるけど cpuが空いていればキューから取り出してすぐに実行されるってこと?
703 名前:デフォルトの名無しさん mailto:sage [2008/05/07(水) 23:01:41 ] 内部的にSendMessage使ってる関数でデッドロックしたことがあるのでマルチスレッド怖い
704 名前:デフォルトの名無しさん mailto:sage [2008/05/07(水) 23:05:04 ] デッドロックはアナライザで一発で見つかるから楽。 問題はコンディションレースだ。
705 名前:デフォルトの名無しさん mailto:sage [2008/05/08(木) 09:27:46 ] >>701 MFCをコンパイルするときは/MLオプションを 受け付けなかったと思ったがどうだっただろう。 /MD と /MTの切り替えは問題なく出来るはず。 さらにVS2005からは/MLは廃止になっている。 一応説明しておくと /MLはシングルスレッド用CRTライブラリのスタティックリンク /MTはマルチスレッド用CRTライブラリのスタティックリンク /MDはMSVCRT.DLL(版によって名称の差異あり)へのダイナミックリンク
706 名前:デフォルトの名無しさん mailto:sage [2008/05/08(木) 11:54:00 ] メッセージキューは必要に応じてスレッドごとに生成される。 自他スレッドやOSから発行されるウインドウメッセージはメッセージキューで並列化され、 メッセージループで読み出されることによってその後のウインドウプロシージャの処理は メッセージループのスレッドで実行される。 つまりマルチなのはキューまでで後は単一のスレッドで実行される。 ただし単純にシーケンシャルに実行されるわけではない。 キューはプライオリティキューであり順番が入れ替わることがある。 ウインドウプロシージャ内でメッセージキューに関係する命令を使った場合、 現在のメッセージの処理を一旦中断し別のメッセージに実行権を譲渡することがある。 >>701 はこの辺を並列で実行されたと誤認してるものと思われる。 どうしてもマルチで動作してると言い張るつもりなら、 ウインドウプロシージャにスレッドIDの変化を調べるルーティンを入れて 変化が認められるか調べるのが一番だと思う。
707 名前:デフォルトの名無しさん mailto:sage [2008/05/08(木) 12:34:36 ] >>706 2行目訂正 誤)メッセージキューで並列化され 正)メッセージキューで直列化され
708 名前:デフォルトの名無しさん mailto:sage [2008/05/08(木) 12:41:26 ] >>701 新しいスレッドを作らない限り同時に実行は無いよ。もっとよく調べてみよう。
709 名前:デフォルトの名無しさん mailto:sage [2008/05/08(木) 13:18:51 ] WndProcがマルチスレッドに動くなら そこらじゅうMutexやらCritical Sessionだらけになる予感 もちろんVolatile論争もこのスレ的にOK
710 名前:デフォルトの名無しさん mailto:sage [2008/05/09(金) 15:43:52 ] 同期コストで逆に遅くなりそうだな。
711 名前:デフォルトの名無しさん mailto:sage [2008/05/11(日) 21:24:19 ] どうせCSocketみたいな内部でPeekMessageで回してるのを見て 同時実行されてると思い込んでるだけでしょ。
712 名前:デフォルトの名無しさん mailto:sage [2008/05/13(火) 20:18:26 ] 何の技術もないんですが、気になってることを質問させてください。 マルチコアプロセッサでマルチスレッドのプログラミングをする時って スレッドを、ポンポンって作って、後はOSとかが暇にしてるコアに 仕事を割り振ってるんですか? それとも、プログラムの側で、「この処理はお前がやれ」ってマルチコアの 特定のコアに指定して割り振るんですか? 調べてみたら、どうも前者っぽいんですが、気になって昨夜は2時間くらい 布団の中で寝れませんでした。お願いします、教えてください。
713 名前:デフォルトの名無しさん mailto:sage [2008/05/13(火) 20:25:47 ] >>712 何も指定しなければOSが自動的に割り振る。 指定すれば割り振ることができる。 だからどっちともいえる。
714 名前:デフォルトの名無しさん mailto:sage [2008/05/13(火) 20:31:19 ] >>713 ありがとう。これで今夜はゆっくり寝れる。 もうひとつ聞きたいこと出てきました。 指定する場合ってどうやるのか、キーワードだけでも 教えていただけると有り難いです。
715 名前:デフォルトの名無しさん mailto:sage [2008/05/13(火) 21:06:27 ] affinityでググればいいんじゃね www.linux.or.jp/JM/html/LDP_man-pages/man2/sched_getaffinity.2.html こんなんとか msdn.microsoft.com/ja-jp/library/cc429346.aspx
716 名前:デフォルトの名無しさん mailto:sage [2008/05/13(火) 21:15:44 ] >>715 あーりーがーとー。 いろんなキーワードで調べてたけど ずっと見つからなかったものが、ようやく見つかった。 感謝します。 お邪魔しました。
717 名前:デフォルトの名無しさん mailto:sage [2008/05/13(火) 22:40:13 ] >>716 Linuxだとtasksetってコマンドで簡単に設定できるので便利。
718 名前:デフォルトの名無しさん mailto:sage [2008/05/13(火) 23:52:00 ] >>717 おぉ。寝る前に念のためにきてみたら、またいいこと知った。 ありがとねー。
719 名前:デフォルトの名無しさん [2008/05/21(水) 17:41:08 ] 質問させて下さい。 WindowsでGUIから何らかのアクションでスレッドを起動し、 ESCキーを押下でメッセージボックスを表示して、 スレッドの実行を中止できるようにしたいと考えています。 こんな風に↓ case IDM_KEY_ESCAPE: { if (thread.suspend()==0) { if (MessageBox(hwnd, "", ""),MB_OKCANCEL)==IDOK) { thread.terminate(); } else { thread.resume(); } } break; } で、以下のようなスレッドクラスを作成しました。 (つづきます)
720 名前:719 [2008/05/21(水) 17:42:31 ] class Thread { HANDLE hthread_; unsigned int id_; void run(void) { /* 具体的な処理 */ } public: void start(void) { hthread_ = (HANDLE)_beginthreadex(NULL, 0, Thread::entrypoint, this, 0, &id_); } DWORD suspend(void) const { return SuspendThread(handle()); } DWORD resume(void) const { return ResumeThread(handle())); } static unsigned int WINAPI entrypoint(void* instance) { thread_t* p = static_cast<thread_t*>(instance); p->run(); _endthreadex(0); CloseHandle(p->handle()); p->hthread_ = 0; return 0; } };
721 名前:719 [2008/05/21(水) 17:43:00 ] しかし、実際に使ってみたところ、ESCキーでメッセージボックスを表示すると、 たしかにスレッドの処理は中断するのですが、 タスクマネージャを見ると中断している間も実行メモリが数KBずつ増えていくのです。 それで中断したまま(メッセージボックスを表示したまま)しばらく放っておくと、 タスクマネージャに表示された該当プロセスのスレッド数が1つ減ります。 (つまりGUI起動時のスレッド数になる) そこでメッセージボックスのOKを選択してスレッドを終了すると、 さらにスレッド数が1つ減って、壊れた振る舞いをするという具合です。 とりあえずスレッドクラスについて質問したいのですが、 ↑は変な実装ではないでしょうか?それから使い方も問題ないでしょうか? OS:Windows Vista x64 言語:C++ 環境:Visual Studio 2008
722 名前:719 mailto:sage [2008/05/21(水) 17:46:25 ] すみません。>>720 のthread_tはThreadの間違い、 p->handle()はp->hthread_、それからterminateメソッドが抜けていました。 void terminate(void) { TerminateThread(hthread_, 0); CloseHandle(hthread_); hthread_ = 0; } }
723 名前:デフォルトの名無しさん mailto:sage [2008/05/21(水) 18:09:32 ] TerminateThreadで終わらせたとき、run内で動的に確保されていたリソースはどうなるでしょうか。 それと、entrypoint内_endthreadex(0)の後に記述した処理は実行されないと思うのですが。 あとは知らん。
724 名前:719 mailto:sage [2008/05/21(水) 18:18:12 ] >>723 どうも。_endthread(0)でスレッドを終了したら、 自動的にentrypointから抜けてしまうのでしょうか?この辺、自信ありません。 (entrypointから抜けるときに_endthreadが呼ばれるというのはMSDNに書いてありましたが…) あとrun内でのメモリの確保は全部boost::shared_ptrを使ってるので問題ないと思います。 いずれにしてもsuspend中に問題が発生しているわけで…。
725 名前:デフォルトの名無しさん mailto:sage [2008/05/21(水) 18:25:16 ] mallocの中でsuspendしたら・・・とか思うと怖いな 何が起きても不思議ではない気がする
726 名前:デフォルトの名無しさん mailto:sage [2008/05/21(水) 18:50:00 ] >>722 TerminateThreadの説明読んだ? こんなおっかねーAPI俺は使ったことないぞ。 強制終了に相当する処理だよ。後始末なんか何もしない。
727 名前:719 mailto:sage [2008/05/21(水) 18:59:04 ] TerminateThreadが危険というのは知識としては知ってますが、 そこに至る前のSuspendThreadの時点で問題が起きているようです。 仮にメッセージボックスでキャンセルを選んで、 TerminateThreadではなくResumeThreadを呼んだ場合でも処理が壊れるのです…。
728 名前:719 mailto:sage [2008/05/21(水) 19:03:28 ] >>725 スレッド内で動的にメモリを確保するのは一般的なことだと思うのですが、 その場合にSuspendThreadを呼ぶタイミングが問題になるなら、 Suspend/ResumeThreadというのはものすごく使いにくい関数な気が。
729 名前:デフォルトの名無しさん mailto:sage [2008/05/21(水) 19:04:04 ] TerminateThread()とか_endthreadex()は、 「呼ばれたらスコープを抜けてローカル変数の解体処理をして…」 なんてことは、一 切 や っ て く れ ま せ ん 。 稼動中のPCの電源を無造作に切るかのようにスレッドの処理を打ち切ってくれます。 shared_ptrのデストラクタなんか呼ばれるわけが無いので、メモリリーク必至です。 で、知っているくせに何でそんなふざけたコード書いてんの?
730 名前:719 mailto:sage [2008/05/21(水) 19:08:11 ] >>729 あ、デストラクタも呼ばれないんですか。それは知りませんでした。勉強になりました。 で、なんでこういうコードを書いているかというと、 危険だというTerminateThreadを何に置き換えるかは後で考えるとして、 とりあえずSuspend/Resumeの部分を実装するために書いたコードなわけで。
731 名前:デフォルトの名無しさん mailto:sage [2008/05/21(水) 19:11:12 ] >>728 そーだよ。 例えばクリティカルセクションに入ったまま止めてしまったら、再開させるまで他のスレッド入れなくなるわけだし。 あと、これ。 msdn.microsoft.com/en-us/library/ms686345 (VS.85).aspx >This function is primarily designed for use by debuggers. >It is not intended to be used for thread synchronization.
732 名前:719 mailto:sage [2008/05/21(水) 19:19:42 ] >>731 なるほど。その"This function is ..."の1文でいろいろ吹っ切れた気が…。 Suspend/Resumeの機能を実装したければ、外からスレッドに何かシグナルを送って、 スレッド自らの手でSuspendする必要があるわけですね。 SuspendThreadはその部分をよきに計らってくれるものだと勘違いしていました。 どうもありがとう〜。
733 名前:デフォルトの名無しさん mailto:sage [2008/05/21(水) 19:32:28 ] まあ精進してちょ。
734 名前:デフォルトの名無しさん mailto:sage [2008/05/21(水) 21:23:54 ] ふつーはイベントを待つ。
735 名前:デフォルトの名無しさん mailto:sage [2008/05/25(日) 07:53:30 ] グローバルにスレッド管理用のフラグを用意する スレッド起動時にこのフラグを1にセット スレッド内で定期的にこのフラグを監視し0になったら途中で終了する メッセージボックスでキャンセルされた時はこのフラグを0にするだけ
736 名前:デフォルトの名無しさん mailto:sage [2008/05/25(日) 08:00:05 ] マルチスレッドだとスタック領域が別になるから グローバルで取ったフラグ用変数のポインタをスレッドに最初に渡すのだよ
737 名前:デフォルトの名無しさん mailto:sage [2008/05/25(日) 08:02:38 ] 別にクラス内のローカルな変数でもいいんだけどね その時はクラスのポインタを渡すのだよ クラス定義を組み込むのを忘れないでね
738 名前:デフォルトの名無しさん mailto:sage [2008/05/25(日) 10:51:14 ] あとvolatileも
739 名前:デフォルトの名無しさん mailto:sage [2008/05/25(日) 11:47:42 ] c/c++のvolatileはいろいろあるから、 ちゃんとmutexなどの同期オブジェクトを使うことをすすめる。 ただwindows限定ならvolatileにメモリバリアの意味があるのだっけ?
740 名前:デフォルトの名無しさん mailto:sage [2008/05/25(日) 13:03:14 ] > c/c++のvolatileはいろいろあるから、 > ちゃんとmutexなどの同期オブジェクトを使うことをすすめる。 もしかして volatile 変数で同期とろうとか思ってる?
741 名前:デフォルトの名無しさん mailto:sage [2008/05/25(日) 13:08:25 ] 荒れる予感
742 名前:デフォルトの名無しさん mailto:sage [2008/05/25(日) 13:10:20 ] >>739 メモリバリアの意味はない。 ただ、IA32はコヒーレントキャッシュだから、volatileだけでも 大して問題がないだけ。
743 名前:デフォルトの名無しさん mailto:sage [2008/05/25(日) 13:18:53 ] ていうかこのケースは知らないが もし「ループを一周余分に回すことになっても問題ない」という 厳密な同期が必要ないものならば、volatileで済むケースはある。 そんなに多くは無いが。
744 名前:デフォルトの名無しさん mailto:sage [2008/05/25(日) 13:34:51 ] >もし「ループを一周余分に回すことになっても問題ない」という >厳密な同期が必要ないものならば、volatileで済むケースはある。 むしろ今回のケースでは一周分余分に回すのがアウトという状況が考えにくい。
745 名前:デフォルトの名無しさん mailto:sage [2008/05/25(日) 14:46:29 ] 一周分余分に回ってアウトなら最初から排他なりセマフォなり入れるしな
746 名前:719 mailto:sage [2008/05/25(日) 16:06:04 ] 結局↓のようなクラスにしました。今のところ問題ありません。 class Thread { HANDLE hthread_, hevent_; unsigned int id_; bool cancel_; void run(void) { while (1) { /* 具体的な処理 */ if (cancel_check()) { return; } } } public: Thread(void) : hevent_(CreateEvent(NULL, TRUE, TRUE, NULL)), cancel_(false) {} ~Thread() { CloseHandle(hevent_); } void start(void) { hthread_ = (HANDLE)_beginthreadex(NULL, 0, Thread::entrypoint, this, 0, &id_); } void cancel(void) { cancel_ = true; SetEvent(hevent_); } void suspend(void) { ResetEvent(hevent_); } void resume(void) { SetEvent(hevent_); } bool cancel_check(void) { if (cancel_) { cancel_ = false; return true; } WaitForSingleObject(hevent_, INFINITE); return false; } static unsigned int WINAPI entrypoint(void* instance) { thread_t* p = static_cast<thread_t*>(instance); p->run(); CloseHandle(p->hthread_); p->hthread_ = 0; return 0; } };
747 名前:デフォルトの名無しさん mailto:sage [2008/05/25(日) 16:37:42 ] run()内で例外投げられたらまずくね
748 名前:デフォルトの名無しさん mailto:sage [2008/05/26(月) 03:02:25 ] >>742 ダウト
749 名前:デフォルトの名無しさん mailto:sage [2008/05/26(月) 03:25:49 ] kwsk
750 名前:デフォルトの名無しさん mailto:sage [2008/05/26(月) 03:27:13 ] OoOの問題じゃないかなと思ったり。
751 名前:デフォルトの名無しさん mailto:sage [2008/05/26(月) 13:30:52 ] UOがどうしたって?
752 名前:匿名 [2008/05/30(金) 15:12:16 ] スレッドは非常に難しいです。 スレッドを利用しないでコンカレントプログラムが容易にできます。 以下のページが参考になります。 www.cspjapan.org/
753 名前:デフォルトの名無しさん mailto:sage [2008/05/30(金) 15:57:17 ] ばか?
754 名前:デフォルトの名無しさん mailto:sage [2008/06/05(木) 15:10:05 ] 生成したスレッドがmallocをしている最中に SuspendThreadするとどんな問題が発生しますか?
755 名前:デフォルトの名無しさん mailto:sage [2008/06/05(木) 15:26:07 ] mallocの中で排他制御しているだろうから、他のスレッドがmallocを呼 ぶと返ってこなくなるかも。
756 名前:デフォルトの名無しさん mailto:sage [2008/06/05(木) 15:27:38 ] mallocがマルチスレッド対応版だと仮定すると、 ヒープ管理データへのアクセスの排他のために mutexを握るタイミングがあるはず そのタイミングでSuspendされると ほかのスレッドがmalloc/free関連の処理をしようとして mutex握れなくてずっと待ちに入る newがmallocをベースにしているならnew/deleteも はたから見るとハングアップに見える
757 名前:デフォルトの名無しさん mailto:sage [2008/06/05(木) 22:23:21 ] >739 C#のvolatileはメモリバリアの意味もあるよ。 C/C++じゃないよ。
758 名前:デフォルトの名無しさん mailto:sage [2008/06/05(木) 22:32:43 ] ふ〜ん
759 名前:デフォルトの名無しさん mailto:sage [2008/06/07(土) 21:41:57 ] MSDNのSystem.Threading.Thread.MemoryBarrierの説明が微妙でわかりづらい >MemoryBarrier は、複数の Intel Itanium プロセッサを使用しているシステムなど、 >ウィーク メモリ オーダリングを採用したマルチプロセッサ システムでだけ使用します。
760 名前:デフォルトの名無しさん mailto:sage [2008/06/07(土) 23:24:59 ] memory orderingの知識がないだけじゃね? strong memory orderingのx86では不要。 シングルプロセッサ(1コア)のシステムでも不要。 weak memory orderingのItaniumを複数使ったシステムでは必要。 書いてあるとおりw memory orderingはこれでも読んどけ ttp://www.arch.ce.hiroshima-cu.ac.jp/~kitamura/public/architecture_2003_13.pdf x86はSPARCのTSOと、ItniumはSPARCのRMOと同じはず
761 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 00:21:36 ] 質問しようと思ったら>>746 に俺が・・・ この場合だとentrypoint内でCloseHandleしてreturn完了後にendthreadex呼ばれるという 挙動であってるのかな?で、ハンドルも問題なく閉じられるのか?
762 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 05:09:09 ] >>746 は無茶苦茶だろ。 とりあえず思ったこと。 ・startで生成したhthreadを別のスレッドでcloseするのが変。 代入前にサブスレッドが終了したらアウチ ・startが2回呼び出されたときのガードは当然してるよな ・とりあえずcancel_はvolatileにしとけ。即座でなくても そのうちtrueが伝わるだろう ・cancelは変数で一時停止がEventだが、どちらかに統一しとけ ・entrypointはprivateにしとけ ・entrypintでrunの例外処理しないとendthreadexが呼ばれない ・キャストはreinterpret_cast使え ・サブスレッドの実行を管理するThreadとサブスレッド処理のクラスを どうして同じにするかな。runとcancel_checkはThreadと別クラスに分離した 方がよいと思う ・_beginthreadexとCreateEventのエラーチェックしろ ・サブスレッドが完了したか調べる関数がほしい あと、Threadがスコープから抜けるとrunのthisが無効になる設計は嫌いだ。 Threadのデストラクタでjoin(WaitForSingleObject(hthread_))すべきだと思う。 呼び出し側が責任を持って事前にcancelを呼び出し、それを怠ったら 不正メモリアクセスでなく永久waitになった方がマシ
763 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 12:08:58 ] 761ですが・・・俺の場合は ・コンストラクタで生成してるけどサスペンドで作成してるから、代入前に終了はないはず ・bool使ってやってます。全体的にこれらの操作はミューテックスで排他してるんですが、 それで十分なんでしょうか? ・ ・ ・なってます ・なるほどやりました。 ・なるほどやりました。 ・実行管理がThreadクラスで、サブ処理がRunnableインタフェースを被ったクラスのrun()メソッド です。Thread自身もRunnableインタフェースを継承してます。(ただしrun()は空) ・失敗してたら何もしないようにしただけです・・・ ・void Thread::join(DWORD timeout){ if(tb == NULL)return; ::WaitForSingleObject(tb->hThread,timeout); } これで十分でしょうか?
764 名前:デフォルトの名無しさん [2008/06/08(日) 13:05:59 ] MSが言っている"アラート可能な待機状態"とはどういう状態のことですか?
765 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 13:08:55 ] 何らかのイベント?とかで待機を中断できるってことじゃね?
766 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 13:11:25 ] 746みたいな事をやるときのboost::threadの楽さと言ったら…。
767 名前:デフォルトの名無しさん [2008/06/08(日) 13:12:39 ] それは、普通の待機状態とアラート可能な待機状態の違いは スレッドプロセスが__cdeclか__stdcallかの違いである ということですか?
768 名前:デフォルトの名無しさん [2008/06/08(日) 13:24:31 ] 違いますね。APCとか理解できません。
769 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 13:55:21 ] >>764 重複I/Oを使うときにのイベント待機に使う。
770 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 19:17:36 ] >764 SleepExとかWaitFor〜Exで、bAlertable=TRUEの状態で寝てるとき
771 名前:762です mailto:sage [2008/06/09(月) 00:32:13 ] >>763 > ・コンストラクタで生成してるけどサスペンドで作成 → 論理的に正しく動くのはわかったけど、わかりづらくない? ハンドル作成したスレッドが(デストラクタあたりで)closeするのが自然だと思うんだが。 > ・bool使ってやってます。全体的にこれらの操作はミューテックスで排他してるんですが、 → startの多重チェックに同期は要らない。なぜならstartは 一つのスレッド(メイン)からしか呼び出さないのが前提だから > Thread自身もRunnableインタフェースを継承してます それはJava APIと同じ設計だけど、APIの設計ミスだと思う。 各クラスの役割は最低限にしようよ。 Runnable: サブスレッドで実行する処理のクラス(主にサブスレッドで使用) Thread: Runnableのスレッド実行を管理するクラス(メインスレッドから使用) 実行制御でもcancel/suspend/resumeは処理固有なのでRunnable側に実装。 スレッドハンドルはスレッド実行管理の話だからThreadでclose。 > void Thread::join(DWORD timeout) できれば戻り値をboolにして DWORD status = ::WaitForSingleObject(?????) if (status == WAIT_ABANDONED) throw ????; return status == WAIT_OBJECT_0; // 完了したかどうか かな。
772 名前:デフォルトの名無しさん mailto:sage [2008/06/09(月) 02:04:45 ] JavaのThreadにケチつけるアホがいるスレはここですか?
773 名前:デフォルトの名無しさん mailto:sage [2008/06/09(月) 02:17:36 ] JavaのThread implements Runnableは失敗だろjk
774 名前:デフォルトの名無しさん mailto:sage [2008/06/09(月) 18:16:32 ] Treadクラスの継承が失敗だろ
775 名前:デフォルトの名無しさん mailto:sage [2008/06/09(月) 23:04:19 ] 761です。もう全然うまくいかないので、なんか言ってもらうために スレッド周辺のプログラムをアップしてみます・・・。include "common.h"は消していいです お願いします>< ttp://ccfa.info/cgi-bin/up/src/up20166.zip
776 名前:デフォルトの名無しさん mailto:sage [2008/06/09(月) 23:06:31 ] よし、何か言ってやる。 >>775 がんばれ!
777 名前:デフォルトの名無しさん mailto:sage [2008/06/10(火) 01:28:22 ] >>775 ○Mutex ・LockでWaitForSingleObjectの戻り値確認しろ。タイムアウトしたら大変なことになるぞ ○Thread ・何でthread_bodyの定義を書く前に変数宣言できるんだ?コンパイル通った? thread_bodyのスマートポインタでないとマズくね? ・start内に例外発生するとマズい場所が多すぎ。line 60,61,62,63,64,68 ・isAliveのロジックが間違ってる。スレッドがSTILL_ACTIVE返したら区別つかない。 WaitForSingleObject(スレッドハンドル) == WAIT_OBJECT_0 で判断しろ ・ThreadProcで(const Thread&)のキャストは要らないでしょ ・マップ操作前後のロックタイミングはこれでいいと思う ・suspend/resumeのロックはこれでいいと思う ・joinでWaitForSingleObjectの戻り値確認して ・isAliveにロックは不要 ・クラス設計が変。currentThreadの返したThreadは何だ? 実際のrunと関係ないrunを持つThreadをnewして返すのは絶対変だ ・Runnableとt_threadの使い分けをもう少し整理して ・ヘッダ名見直せ。<cstdio><windows.h><process.h><map><cstdio><sstream> > tb=thread_pool_for_runnable[target];//既にあるRunnableの時はそれを使う ? エラー返すべきでは? あと、ミューテックスのロックはヘルパークラス作れ。 コンストラクタでミューテックスを受け取ってロックし、デストラクタでアンロック。 でないと途中で例外が発生したときにいちいち対処できない。 > もう全然うまくいかないので 何がうまくいかない? 何となく動きそうだが。 コンパイルエラーとか言ったら殺
778 名前:デフォルトの名無しさん mailto:sage [2008/06/10(火) 07:15:40 ] 今携帯なんで、後で詳しく見ますが、うまくいかないというのは これで画像読み込みをしたときに画像読み込みが出来なかったりするんです 実験中には終了時に不正アクセスみたいのが出たり…
779 名前:デフォルトの名無しさん mailto:sage [2008/06/10(火) 14:38:51 ] 777が優しすぎる 俺が男なら惚れてたね
780 名前:デフォルトの名無しさん mailto:sage [2008/06/10(火) 14:56:56 ] 俺は男だから惚れた
781 名前:デフォルトの名無しさん mailto:sage [2008/06/10(火) 16:38:37 ] じゃあ掘れるのか
782 名前:デフォルトの名無しさん mailto:sage [2008/06/10(火) 19:43:21 ] 惚れたけど掘れない。
783 名前:719 mailto:sage [2008/06/10(火) 20:22:05 ] いやぁ、勉強になるなぁ…。
784 名前:デフォルトの名無しさん mailto:sage [2008/06/11(水) 07:10:26 ] 質問があります pthreadでは途中でスレッドをキャンセルする場合 pthread_cancelを遅延キャンセルでコールして、 クリーンナップハンドラでリソースを開放するという方法が考えられますが、 C++では実行環境(gcc,glibc)によって、クリーンナップ内でオブジェクトの デストラクタが呼ばれなかったり、例外処理が行われないなどといったことがあるみたいですが、 「C++ではこのようにしてpthreadを中段させるべき」といった 定石的手法が確立しているのでしょうか? できればURIなど情報源などもあれば教えてください。 【OS】 Linux2.6 【言語】 C++ 【実行環境】 RHEL5(pthread) 【その他突起する事項】 「RHEL5の中のライブラリならサポートしてるので気にするな」ってのは無しで
785 名前:デフォルトの名無しさん mailto:sage [2008/06/11(水) 07:47:54 ] 外から中断なんかしない。 当たり前すぎて泣けてくる。
786 名前:デフォルトの名無しさん mailto:sage [2008/06/11(水) 12:24:11 ] >>784 安全に中断させる方法なんて存在しない。 だが、スレッドのエントリ関数のreturnを実行して正しく終了させる方法はいくらでもある。
787 名前:デフォルトの名無しさん mailto:sage [2008/06/11(水) 13:55:11 ] > 「C++ではこのようにしてpthreadを中段させるべき」といった > 定石的手法が確立しているのでしょうか? 中断通知機構は自分で独自に実装。必ずエントリポイントの関数まで 戻るようにする。 異常時に終了するため、終了用の例外クラスを作成。エントリポイントのみ でcatchし、他はクラスに対し例外中立なコードを書く。 ソースは俺。
788 名前:デフォルトの名無しさん mailto:sage [2008/06/11(水) 14:04:26 ] >>778 joinせずに終了したか、Thread,Runnableのメモリが誤って解放されたのでは
789 名前:デフォルトの名無しさん mailto:sage [2008/06/11(水) 20:40:04 ] スレッド止めてプロセスにする
790 名前:777 mailto:sage [2008/06/11(水) 21:51:22 ] >>775 GetLastErrorの戻り値判定ロジックが逆。 細かい間違いは修正したが普通に動いた。元のろだ?のup方法がわからなかったので↓にup www11.axfc.net/uploader/He/so/108823.zip DLパスは mt さすがにmy_ptrとかいうのはboost::shared_ptrに置き換えさせてもらった。
791 名前:デフォルトの名無しさん mailto:sage [2008/06/11(水) 22:28:58 ] アクターモデルって奴の C++とかjavaとかでのサンプルない?
792 名前:デフォルトの名無しさん mailto:sage [2008/06/11(水) 22:36:55 ] 761です >>790 ブワッ!なんと言うやさしさ・・・やっと時間が取れたので、777を元に修正してたら、なんという でも俺はウホじゃないです。すいません (const Thread&)のキャストですが、こうしたらローカル変数の寿命がどうたらで1個分生成・破棄の コストが浮くかなあと思って付けたんですが・・・まぁ、確認もせずにつけたので効果はいざ知れず > currentThreadの返したThreadは何だ? この関数を実行したスレッドがスレッドプール内に存在すれば、そのスレッドを操作する Threadオブジェクトを返します。 既存のRunnableの時再利用するのは Hoge(){ Thread th(this);th.start(); } ~Hoge(){ Thread(this).join(); } とすることに憧れていたからです・・・。つまり俺がちょっとおかしいのです
793 名前:デフォルトの名無しさん mailto:sage [2008/06/11(水) 23:27:08 ] pthread mutexで 読みスレッドが2人 書きスレッドが2人 といる場合、rwlock使うと読んでる間に 書き込もうとしてもロックされる?
794 名前:デフォルトの名無しさん mailto:sage [2008/06/12(木) 00:24:12 ] pthreadは知らないけど一般のReader-Writer-Lockなら排他制御されなぎまずいんじゃね。 Readerのみの場合に排他されないんだと思う。 Reader vs. Reader → 排他されない Reader vs. Writer → 排他される Writer vs. Writer → 排他される
795 名前:デフォルトの名無しさん mailto:sage [2008/06/12(木) 00:38:59 ] Pthreadもそうだったと思う Man読みゃいいんだけどね
796 名前:デフォルトの名無しさん mailto:sage [2008/06/12(木) 01:47:42 ] スレッドAがrdlockする スレッドBがwrlockしようとする(が、rdlock中なのでブロック) この状態の時に、スレッドCがrdlockしようとすると 1.スレッドCがrdlockを取得(Aと共存)出来る 2.スレッドB(ロック獲得優先権がある)の処理終了までブロックする 一般的にはどうなる? ・一般的に、rwlockと呼ばれるものの動作として決まっている(どっち?) ・pthreadの標準として決まっている(どっち?) ・何も決まってない(実装依存)
797 名前:デフォルトの名無しさん mailto:sage [2008/06/12(木) 01:54:39 ] >>796 opengroup.org/onlinepubs/007908775/xsh/pthread_rwlock_rdlock.html > It is unspecified whether the calling thread acquires the lock > when a writer does not hold the lock and there are writers waiting for the lock. 何も決まってないぽい
798 名前:デフォルトの名無しさん mailto:sage [2008/06/12(木) 02:00:50 ] おー、thx