- PR -

スレッドの一時停止および再開について(マルチスレッド)

投稿者投稿内容
freebird
常連さん
会議室デビュー日: 2006/11/07
投稿数: 22
投稿日時: 2006-11-29 18:45
こんばんわ。
VC++.NET2003を用いてコンソールプログラミングを行なっています。記述はほとんどがC言語ライブラリで、マルチスレッドに関しても(_beginthreadex関数)を用いています。スレッドの停止および再開を行なう場合は、Winsows 32API関数を用いています。

そこで、スレッドの停止および再開について質問します。
Windows 32API関数にWaitForSingleObject、SetEvent、ReSetEventおよびSuspendThread、ResumeThread関数があります。

この両者の関数を用いてスレッドの停止と再開をさせることができているのですが・・・
両者の違いはどういう所にあるのでしょうか?

前者は、スレッド自体停止していないが、後者の場合は完全に停止状態になっている?という違いなのでしょうか?

私は現在、winsockにてソケットプログラミングを行なっています。その際、スレッドの停止および再開を用いたいのですが、どちらが適している?などはあるのでしょうか?

もしよろしければ、参考になるテキスト等を教えていただければと思います。

よろしくお願い致します。
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2006-11-29 19:30
引用:

Windows 32API関数にWaitForSingleObject、SetEvent、ReSetEventおよびSuspendThread、ResumeThread関数があります。

この両者の関数を用いてスレッドの停止と再開をさせることができているのですが・・・
両者の違いはどういう所にあるのでしょうか?

前者は、スレッド自体停止していないが、後者の場合は完全に停止状態になっている?という違いなのでしょうか?



前者は「待機(ブロック)」状態です。
待機状態に陥るのは、ワーカスレッドが WaitForSingleObject() 呼び出しを行った時(箇所)です。

後者は「休眠」状態です。
いつ(or どこで)休眠状態に陥るか、ワーカスレッドに選択権はありません。

引用:

スレッドの停止および再開を用いたいのですが、どちらが適している?などはあるのでしょうか?



大抵、ワーカスレッドが「とりあえず止まりゃいい/動きゃいい」なんてことはなく、「計画的な制御」が必要とされるはずで、そのためにはイベントやミューテックスなどの同期オブジェクトを使います。

Suspend/Resume はワーカスレッドの起動タイミングの調整くらいにしか使ったことないです>わたし


_________________
// 渋木宏明 (Hiroaki SHIBUKI)
// http://hidori.jp/
// Microsoft MVP for Visual C#

[ メッセージ編集済み 編集者: 渋木宏明(ひどり) 編集日時 2006-11-29 19:31 ]
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2006-11-29 19:40
こんばんは。

引用:

freebirdさんの書き込み (2006-11-29 18:45) より:

そこで、スレッドの停止および再開について質問します。
Windows 32API関数にWaitForSingleObject、SetEvent、ReSetEventおよびSuspendThread、ResumeThread関数があります。
この両者の関数を用いてスレッドの停止と再開をさせることができているのですが・・・
両者の違いはどういう所にあるのでしょうか?



説明が難しいですが、”停止”と”待機”の違いでしょうか。

SuspendThread、ResumeThread関数は、あるスレッドを外部のスレッドが”強制的”に停止・再開させます。
Eventオブジェクトはスレッド間/プロセス間の”同期”をとるために使います。スレッドは自主的に待機をすることになります。

引用:

私は現在、winsockにてソケットプログラミングを行なっています。その際、スレッドの停止および再開を用いたいのですが、どちらが適している?などはあるのでしょうか?



直感的には、同期オブジェクト(イベントオブジェクトなど)を使うほうが正しいでしょう。
SuspendThread、ResumeThread関数は乱用するようなものではないと思います。

freebird
常連さん
会議室デビュー日: 2006/11/07
投稿数: 22
投稿日時: 2006-11-30 12:27
返信ありがとうございます。

停止と待機について詳しく学習したいと思います。

そこでこの場をかりて、もう一つ質問なのですが・・・
私は、スレッドを一つのプログラムに2つ以上記述しているためソースが少し長くなっています。他のサンプルプログラムを見たところ、スレッドだけヘッダファイル?(拡張子がcppになっていたので違うのでしょうか・・・)にすることで見やすくしていました。

メイン処理(main.cpp)
1つ目のスレッド
2つ目のスレッド

と分割して記述し、まとめてコンパイル→実行はできるのでしょうか?
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2006-11-30 13:48
引用:

と分割して記述し、まとめてコンパイル→実行はできるのでしょうか?



もちろんです。

スレッドプロシージャも所詮は関数(あるいは暮らすメソッド)なわけで、C/C++ 言語の仕様に合致した記述になっていれば、.cpp や .h ファイルをいくつにでも分割できます。
freebird
常連さん
会議室デビュー日: 2006/11/07
投稿数: 22
投稿日時: 2007-01-09 23:31
こんばんわ。
以前作りましたスレッドに質問を投稿させていただきます。

_beginthreadexでスレッド1と2を生成しました。そして、スレッド1と2の同期をとりたいと思いWaitForSingleObject、SetEvent、ResetEvent関数を用いて同期をとるようにプログラムを製作しました。

[質問内容]
以下にプログラムの概要を示します。
スレッド2がWaitForSingleObject関数で待機状態となり、スレッド1のSetEvent関数により待機状態のスレッド2が再開されると言うプログラムです。

これらの関数を用いて、スレッド2を待機→再開を頻繁に繰り返しているのですが・・
このようなやり方は、実際のソフトウェアでありえることなのでしょうか?

また、スレッド2が待機から再開される、時間を計測したのですが30ms以上あります。スレッドの待機・再開には時間がかかるのでしょうか?

・スレッド1
SetEvent(hEvent[0]);

・スレッド2
SUSPEND_INTERVAL=20
if(Num%SUSPEND_INTERVAL==0){
WaitForSingleObject(hEvent[0],INFINITE);
ResetEvent(hEvent[0]);
}

あやふやな質問かもしれませんが、よろしくお願い致します。
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2007-01-09 23:43
引用:

freebirdさんの書き込み (2007-01-09 23:31) より:
[質問内容]
これらの関数を用いて、スレッド2を待機→再開を頻繁に繰り返しているのですが・・
このようなやり方は、実際のソフトウェアでありえることなのでしょうか?


よくありますよ。処理すべきデータの準備が整うまで待機するとか・・・

引用:

また、スレッド2が待機から再開される、時間を計測したのですが30ms以上あります。スレッドの待機・再開には時間がかかるのでしょうか?


いいえ、計測するほどの遅延はありません。スレッド2よりもプライオリティの高いスレッドが動作していたり、あるいは同じプライオリティのほかのスレッドが動作中だったために、遅延が発生したのでしょう。
freebird
常連さん
会議室デビュー日: 2006/11/07
投稿数: 22
投稿日時: 2007-01-09 23:49
返信ありがとうございます。

引用:

甕星さんの書き込み (2007-01-09 23:43) より:
いいえ、計測するほどの遅延はありません。スレッド2よりもプライオリティの高いスレッドが動作していたり、あるいは同じプライオリティのほかのスレッドが動作中だったために、遅延が発生したのでしょう。



計測するほどの遅延はないとのことですが・・・、計測することができないほどの遅延、いわゆるマイクロ秒単位での処理が実行されている?とのことでしょうか?

例えば、printfなどの関数が処理される時間と見ればよいのでしょうか?

スキルアップ/キャリアアップ(JOB@IT)