マルチスレッドプログラミングについていくつか教えて下さい。
マルチスレッドの基礎がまだ分かってないので初心者でも分かり易いようにお願いします。
1:イベントオブジェクトについて教えて下さい。
「イベントオブジェクト」の概念がよく分かりません。
○シグナル状態と非シグナル状態とはどういう状態なのでしょうか?
○自動リセットの場合ではどのタイミングで切り替わっているのでしょうか?(下記のソースの場合)
○手動リセットの場合ではどのタイミングで切り替えればよいのでしょうか?(下記のソースの場合)
2:CloseHandle() と ExitThread() について教えて下さい。
○この2つの関数の役割の違いについて教えて下さい。
「スレッドハンドルを閉じる=スレッドを終了」ではないのでしょうか?
また、これらの関数実行時にシグナル状態は気にする必要はありますか?(シグナル状態にしなくてよいのか?)
下記のソースは簡略化のためかなり省略されています。
DWORD WINAPI ThreadProc( DWORD i )
{
while( true )
{
DWORD r = WaitForMultipleObjects( 2, hEvent, FALSE, INFINITE );
if( r == WAIT_OBJECT_0 )
{
// 処理1
}
else if( r == WAIT_OBJECT_0 )
{
// 処理2
}
else
{
ExitThread( TRUE ); // スレッド終了
}
}
}
void MainProc()
{
// 自動リセットのイベントオブジェクト作成
for( int i=0; i<2; i++ )
{
hEvent[i] = CreateEvent( NULL, FALSE, FALSE, NULL );
}
// スレッドを作成
hThread = CreateThread( NULL, 0, ThreadProc, NULL, 0, &dwThreadID );
}
No.2ベストアンサー
- 回答日時:
>・自動リセットは自動でシグナルと非シグナルを切り替えてくれるものだと思っていたのですが、間違っているのでしょうか?
違います。シグナルを受け取った時に自動的にリセットする(非シグナルに切り替える)だけで、勝手にシグナル状態にはしません。
>初期状態が非シグナルなのでこのまま変化しないということはスレッドはずっと動かないということですか?
そのはずです。
>シグナル状態になったときに制御を返すとありますが、シグナル状態ではなく非シグナル状態になるのですか?
シグナル状態になったから制御を返しますが,返すときにリセット動作する(非シグナル状態にする)だけです。
自動リセットを使う場合は、WaitObjedtて止まっているスレッドを動かすことにあるので、動いてしまえば非シグナル状態にしても問題ありません。
>初期状態に非シグナルを指定していてもちゃんと返ってきます
多分エラーで戻っているのでは。イベント作ったプロセス終了しているように見えますが、問題ないですか?
INFINITEが指定されているのでシグナル状態になるまで戻ってこないはずです。
時間が設定してあれば、タイムアウトで戻ってきますけど。
通常勝手にSetEventが呼ばれることは無いと思います。
>スレッドを使わなくなったときはどっちを使うべきでしょうか?
ExitThread()
CreateThread()についてもう一度読んでください。
これに限らず、たいていマニュアルにあると思いますが。
ちなみに、古いWIN32APIのHELP読んだだけで回答してますので、自信無しです。
他のOSでは似たことやってますし、Windowsでもイベントでなくメッセージでプロセス間WaitForMultipleObjectsは使ったことありますが。
No.3
- 回答日時:
なんらかの同期オブジェクト(例えばイベント)がシグナル状態・非シグナル状態のどちらであっても、スレッドが勝手にサスペンドすることはありません。
同期オブジェクトがシグナル状態であれば、その同期オブジェクトを指定してWaitFor???()を呼び出せば、すぐに戻ってきます。非シグナル状態であれば、シグナル状態になるか、タイムアウトするまで、WaitFor???()から戻ってきません。(呼び出したスレッドはサスペンド状態になり、その間CPU時間は割り当てられない)
自動リセットイベントは、初期状態をリセット状態であるようにします。このイベントを待つ必要があれば、WaitFor???()を呼び出します。別のスレッドが、このイベントをセットすることで、このイベントを待っていたスレッドがWaitFor???()から戻ります(=サスペンドが解除される)。再度このイベントを待つ前に誰かがイベントをリセットしてやらないとイベントの意味が無くなってしまうのですが、このイベントを待っていたスレッドを通過させると同時にイベントもリセットさせるのが自動リセットイベントです。
待つ→セット→待つ→セットの繰り返しだけで同期が取れるようになっています。
シグナル状態=青信号、非シグナル状態=赤信号、信号を見て止まるかどうかは、WaitFor???()の呼び出しと理解するといいでしょう。止まっているものを動かすには、別の誰かが信号を青にしてやる必要があります。
スレッドハンドルは、スレッドの生存状態と同期を取る為にも使用されるので、ExitThread()やTerminateThread()によってスレッドが終了しても、スレッドハンドルは有効です。スレッドハンドルはスレッドそのものでは無いので、スレッドハンドルをクローズしても、スレッドは終了しません。
スレッドが終了しているかどうかに関係なく、不要になったスレッドハンドルは自分でCloseHandle()を呼び出して開放してやる必要があります。(もちろんプロセス終了時には全てのハンドルがクローズされます)
No.1
- 回答日時:
Windowsですよね。
この種の内容はOSによって異なりますのでご注意を。>○シグナル状態と非シグナル状態とはどういう状態なのでしょうか?
イベントを待つプロセス,スレッドが動作できる状態がシグナル状態、そうでないのが非シグナル状態です。
WaitForMultipleObjects()等でイベントを待っているスレッドなどはシグナル状態になるまで、
実行を止めて待ちます。
>○自動リセットの場合ではどのタイミングで切り替わっているのでしょうか?
SetEvent()がないため、初期状態(非シグナル)のまま変化しません。
もし、どこかでSetEvent()が呼ばれた場合,その時点でイベントがシグナル状態になり、スレッドが動作し、
> DWORD r = WaitForMultipleObjects( 2, hEvent, FALSE, INFINITE );
のWaitForMultipleObjects()の関数から帰る時に、
非シグナル状態になります。
>○手動リセットの場合ではどのタイミングで切り替えればよいのでしょうか?
プログラムの目的、内容等によります。
自動でなく手動にするなら何らかの目的があるはずなので。
特に何もなければ、自動と同じでいいでしょう・・というか、自動を使いましょう。
>○この2つの関数の役割の違いについて教えて下さい。
ExitThread()はスレッドを終了させるためのもので、
CloseHandle() はハンドルを閉じるための物です。
実際の処理内容は異なります。
例えば,ExitThread()が呼ばれてもスレッドハンドルはクローズされない場合があります。
>関数実行時にシグナル状態は気にする必要はありますか?(シグナル状態にしなくてよいのか?
処理内容によります。
まあ、フェイルセーフ,理解を深めるという意味で,常に気にしていた方がいいかも知れませんが。
ご回答ありがとうございます。
でもまだイベントオブジェクトが理解できません・・・
>Windowsですよね。この種の内容はOSによって異なりますのでご注意を。
・書き忘れていました。すみません。OSはWindowsXPです。
>>○自動リセットの場合ではどのタイミングで切り替わっているのでしょうか?
>SetEvent()がないため、初期状態(非シグナル)のまま変化しません。
>もし、どこかでSetEvent()が呼ばれた場合,その時点でイベントがシグナル状態になり、スレッドが動作し、
>> DWORD r = WaitForMultipleObjects( 2, hEvent, FALSE, INFINITE );
>のWaitForMultipleObjects()の関数から帰る時に、
>非シグナル状態になります。
・自動リセットは自動でシグナルと非シグナルを切り替えてくれるものだと思っていたのですが、間違っているのでしょうか?
「スレッドが動作できる状態=シグナル状態」なんですよね?
初期状態が非シグナルなのでこのまま変化しないということはスレッドはずっと動かないということですか?
・MSDNにはWaitForMultipleObjects関数はシグナル状態になったときに制御を返すとありますが、シグナル状態ではなく非シグナル状態になるのですか?
それに初期状態に非シグナルを指定していてもちゃんと返ってきますが、これはどこかでSetEvent関数が呼ばれていると考えてよいのでしょうか?
>>○この2つの関数の役割の違いについて教えて下さい。
>ExitThread()はスレッドを終了させるためのもので、
>CloseHandle() はハンドルを閉じるための物です。
>実際の処理内容は異なります。
>例えば,ExitThread()が呼ばれてもスレッドハンドルはクローズされない場合があります。
>>関数実行時にシグナル状態は気にする必要はありますか?(シグナル状態にしなくてよいのか? )
>処理内容によります。
>まあ、フェイルセーフ,理解を深めるという意味で,常に気にしていた方がいいかも知れませんが。
・どういう時に使い分けをしたらよいのでしょうか?
スレッドを使わなくなったときはどっちを使うべきでしょうか?それとも両方ですか?
質問が多くなってしまって申し訳ございません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- Excel(エクセル) Excelでnullになるような式のセルをマクロで空白行と認識させるにはどうすればいいですか? 3 2023/03/13 13:42
- C言語・C++・C# C# DatagridviewにExcelシートを反映するとエラーが出る 2 2023/05/06 17:12
- PHP ここでの ②if($su_d<>"")の比較演算子 を使う理由は 1 2022/03/26 02:33
- Visual Basic(VBA) EXCEL VBAにて動的にCheckBOXを複数作成し、同BOXにイベントを追加したい 1 2023/03/16 07:05
- PostgreSQL DBFluteについて質問です。 環境:PostgreSQL java8 前提:webアプリケーショ 1 2022/07/07 00:49
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- Visual Basic(VBA) VBAのトグルボタンでのマクロについて質問です 3 2022/10/10 17:23
- Java java 引数 戻り値のあるメソッド 3 2023/02/12 06:23
- Excel(エクセル) エクセルVBAでオブジェクトが必要です 2 2022/09/10 16:37
このQ&Aを見た人はこんなQ&Aも見ています
-
【お題】NEW演歌
【大喜利】 若い人に向けたことは分かるけど、それはちょっと寄せ過ぎて変になってないか?と思った演歌の歌詞
-
大人になっても苦手な食べ物、ありますか?
大人になっても、我慢してもどうしても食べれないほど苦手なものってありますよね。 あなたにとっての今でもどうしても苦手なものはなんですか?
-
忘れられない激○○料理
これまでに食べたもののなかで、もっとも「激○○」だった料理を教えて下さい。 激辛、でも激甘でも。 激ウマ、でも激マズでも。
-
許せない心理テスト
私は「あなたの目の前にケーキがあります。ろうそくは何本刺さっていますか」と言われ「12本」と答えたら「ろうそくの数はあなたが好きな人の数です」と言われ浮気者扱いされたことをいまだに根に持っています。
-
【大喜利】【投稿~11/22】このサンタクロースは偽物だと気付いた理由とは?
【お題】 ・このサンタクロースは偽物だと気付いた理由とは?
-
WaitForSingleObjectの使い方について
C言語・C++・C#
-
DWORDの実際の型は何でしょうか
C言語・C++・C#
-
静的でないメンバ関数の呼び出しが正しくありません
C言語・C++・C#
-
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/22】このサンタクロースは偽物だと気付いた理由とは?
- ・お風呂の温度、何℃にしてますか?
- ・とっておきの「まかない飯」を教えて下さい!
- ・2024年のうちにやっておきたいこと、ここで宣言しませんか?
- ・いけず言葉しりとり
- ・土曜の昼、学校帰りの昼メシの思い出
- ・忘れられない激○○料理
- ・あなたにとってのゴールデンタイムはいつですか?
- ・とっておきの「夜食」教えて下さい
- ・これまでで一番「情けなかったとき」はいつですか?
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
MFC通信プログラムマルチスレッ...
-
マルチスレッドでブレイクポイ...
-
スレッドの監視方法について
-
Windows上で、シグナル(SIGTERM...
-
WaitForSingleObjectの使い方に...
-
マルチスレッド内のループについて
-
CWnd::OnTimerのスレッドの取得
-
VC++スレッドの正しい終了のさ...
-
待機関数(WaitForMultipleObjec...
-
スレッドにて同一メモリの書き...
-
スレッドの安全な終了のさせ方
-
スレッドの終了の仕方
-
C++ GUIのメッセージループ。
-
Macターミナルで実行中のプログ...
-
バックグラウンドのプロセスの...
-
C# シリアル通信でデータ受信...
-
C言語で、メモリを解放しないで...
-
「キャンセル」ボタン付きの処...
-
C#でのbatファイル実行結果取得
-
プロダクションコードとは?
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VC++スレッドの正しい終了のさ...
-
スレッドの監視方法について
-
Windows上で、シグナル(SIGTERM...
-
WaitForSingleObjectの使い方に...
-
スレッドの安全な終了のさせ方
-
スレッドの終了の仕方
-
MFC通信プログラムマルチスレッ...
-
マルチスレッドプログラミング...
-
別スレッドからメインダイアロ...
-
マルチスレッドについて
-
.NetのBackgroundWorkerクラス...
-
スレッドにて同一メモリの書き...
-
別スレッドのデータを受信できない
-
同一スレッドで、ロックをかけ...
-
マルチスレッドの同期方法
-
スレッドの終了はどうやるんで...
-
待機関数(WaitForMultipleObjec...
-
msec単位のWait Timerが作れない!
-
CWnd::OnTimerのスレッドの取得
-
_beginthreadexで生成したスレ...
おすすめ情報