
マルチスレッドプログラミングについていくつか教えて下さい。
マルチスレッドの基礎がまだ分かってないので初心者でも分かり易いようにお願いします。
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も見ています
関連するカテゴリからQ&Aを探す
今、見られている記事はコレ!
-
釣りと密漁の違いは?知らなかったでは済まされない?事前にできることは?
知らなかったでは済まされないのが法律の世界であるが、全てを知ってから何かをするには少々手間がかかるし、最悪始めることすらできずに終わってしまうこともあり得る。教えてgooでも「釣りと密漁の境目はどこです...
-
カスハラとクレームの違いは?カスハラの法的責任は?企業がとるべき対応は?
東京都が、客からの迷惑行為などを称した「カスタマーハラスメント」、いわゆる「カスハラ」の防止を目的とした条例を、全国で初めて成立させた。条例に罰則はなく、2025年4月1日から施行される。 この動きは自治体...
-
なぜ批判コメントをするの?その心理と向き合い方をカウンセラーにきいた!
今や生活に必要不可欠となったインターネット。手軽に情報を得られるだけでなく、ネットを介したコミュニケーションも一般的となった。それと同時に顕在化しているのが、他者に対する辛らつな意見だ。ネットニュース...
-
大麻の使用罪がなかった理由や法改正での変更点、他国との違いを弁護士が解説
ドイツで2024年4月に大麻が合法化され、その2ヶ月後にサッカーEURO2024が行われた。その際、ドイツ警察は大会運営における治安維持の一つの方針として「アルコールを飲んでいるグループと、大麻を吸っているグループ...
-
ピンとくる人とこない人の違いは?直感を鍛える方法を心理コンサルタントに聞いた!
根拠はないがなんとなくそう感じる……。そんな「直感がした」という経験がある人は少なくないだろう。ただ直感は目には見えず、具体的な説明が難しいこともあるため、その正体は理解しにくい。「教えて!goo」にも「...
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
スレッドの監視方法について
-
CWnd::OnTimerのスレッドの取得
-
WaitForSingleObjectの使い方に...
-
VC++ Workerスレッドを強制終了...
-
マルチスレッドの実行順序の制御
-
同一スレッドで、ロックをかけ...
-
VC++スレッドの正しい終了のさ...
-
Linuxでスレッド優先度って変え...
-
スレッドの終了の仕方
-
マルチスレッドについて
-
スレッドの安全な終了のさせ方
-
excelvbaでCreateThreadの動作
-
C#でスレッド実行中のイベント...
-
スレッドについて
-
Win32APIでのスレッド処理
-
マルチスレッドのスレッド数を...
-
メインダイアログが最背面に表...
-
.netアプリへのSendMessageでフ...
-
スレッドの監視方法
-
別スレッドのデータを受信できない
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
スレッドの監視方法について
-
VC++スレッドの正しい終了のさ...
-
スレッドの終了の仕方
-
WaitForSingleObjectの使い方に...
-
Windows上で、シグナル(SIGTERM...
-
別スレッドのデータを受信できない
-
スレッドの安全な終了のさせ方
-
スレッドにて同一メモリの書き...
-
別スレッドからメインダイアロ...
-
マルチスレッドのスレッド数を...
-
C# スレッド終了の監視について
-
MFC通信プログラムマルチスレッ...
-
Linuxでスレッド優先度って変え...
-
メインダイアログが最背面に表...
-
スレッドの終了はどうやるんで...
-
CWnd::OnTimerのスレッドの取得
-
C# スレッドから親ウィンドウへ...
-
メインスレッドのPostMessageと...
-
msec単位のWait Timerが作れない!
-
.NetのBackgroundWorkerクラス...
おすすめ情報