[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 2chのread.cgiへ]
Update time : 05/09 09:53 / Filesize : 193 KB / Number-of Response : 799
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

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



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】

【言語】

【実行環境】

【その他突起する事項】

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 ]
荒れる予感






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<193KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef