- ベストアンサー
【C++】セマフォとプロセスの使い方
- WindowsXPでVC++2008コンパイラを使用して、プロセスとセマフォについて勉強しています。外部プログラムを複数立ち上げる際の制限について教えてください。
- スレッドを使用したセマフォのサンプルがありますが、プロセスを使用する場合の書き方がわかりません。アドバイスをお願いします。
- 現在のコードはプロセスを生成するループが実装されていません。プロセスの制限を設定して外部プログラムを起動する方法を教えてください。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
今回の場合、スレッドはプロセスを起動した後は終了を待つだけなので、WaitForSingleObjectで待機状態にするなら、それは別に構わないと思います。前の書き方だと、スレッドを外部から停止させて、プロセス終了を判定した後に再開させるように受け取れたので…… > この場合、GetExitCodeProcessの方がどうして楽なのでしょうか? プロセスを起動したスレッド自身で終了判定を行うことにした方が、プロセス情報等のデータをスレッド内部に限定できるので、カプセル化が容易になります。各スレッドの処理は基本的に同じことをしてるだけなので、扱うデータを内部に閉じ込められるなら、メインスレッドは各スレッドの中のことは意識せず、単に繰り返しで同様のスレッドを生成・起動するだけで済みます。 これをそのスレッド以外で行うとすると、当然、プロセス情報等の管理をスレッドの外で行う必要があり、スレッドとの関連づけで管理するとかの工夫が必要になります。ま、プロセス情報ぐらいならそんなに考える必要もありませんが、これがもっと複雑な処理を行うスレッドで、多くのデータを用いて状態管理してるとかなると、外部管理するのは現実的ではありません。 > スレッドから立ち上げたプロセスを一時停止、再開させる方法にはどのようにすれば宜しいでしょうか。 プロセスの停止とか再開とかは分かりません。自作のソフトならそれこそセマフォなりミューテックスなりを使った排他制御の機能を仕込んでおいて停止させることは出来ると思いますが、そうでない既製のアプリを停止させるというのは……
その他の回答 (3)
- magicalpass
- ベストアンサー率58% (378/648)
セマフォがデッドロックになったりせず、スレッドが放置されたりしないかぎりはどういう形で機能を実現しても構わないと思いますが、スレッドを停止させた場合は外部(メインスレッド等)から再開させたりする必要がありますが、かえって面倒じゃないですか?
補足
ご回答、ありがとうございます。 前回の補足を誤って書いてしまいました。 (誤) >因み今回紹介して頂いたGetExitCodeProcessを使わずに >GetExitCodeProcessを使ってプロセスが終了するまで、 >プロセスを立ち上げたスレッドを停止させておく >ことはまずいですか? (正) >WaitForSingleObject(pi.hProcess,INFINITE);を使って >プロセスが終了するまで >プロセスを立ち上げたスレッドを停止させておく >ことはまずいですか? >スレッドを停止させた場合は外部(メインスレッド等)から >再開させたりする必要がありますが、かえって面倒じゃないですか? この場合、GetExitCodeProcessの方がどうして楽なのでしょうか? また、別で質問しようと思いましたが、ついでに教えてください。 スレッドから立ち上げたプロセスを一時停止、再開させる方法には どのようにすれば宜しいでしょうか。
- magicalpass
- ベストアンサー率58% (378/648)
上にあげられてるようなコードで既製のアプリを起動するプロセスの生成元でセマフォの管理をしようとしてもちゃんと動きません。 なぜなら、既製のアプリ自身はセマフォにアクセスしていないから、処理が終わってもセマフォは解放されない。したがって、セマフォの解放を待ってる生成元に処理が復帰しないからです。 プロセスの終了を判断するならWaitForSingleObjectを待っていてはだめです。CreateProcessで返ってきたプロセス情報piを利用して判定するしかありません。 処理順序としては (1)CreateSemaphore(セマフォ生成) (2)WaitForSingleObject(セマフォ解放待ち) (3)CreateProcess(プロセス生成) (4)プロセス終了待ち (5)ReleaseSemaphore(セマフォ解放) (6)CloseHandle(セマフォ廃棄) 実装としては(2)~(5)は独立したスレッドにした方が管理がしやすいだろうから、結局のところはサンプルにあるスレッド制御をそのまま使い、そのスレッドの処理内容として(3)(4)を行うという形が現実的だと思いま す。 プロセスが終了してるかどうかはGetExitCodeProcessを使えば分かるはずなので、各スレッドはCreateProcessした後はループでSleepを繰り返しながらプロセスの終了を待つ形で良いと思います。
補足
ご回答、ありがとうございます。 その方針で成功しました。有難うございました。 因み今回紹介して頂いたGetExitCodeProcessを使わずに GetExitCodeProcessを使ってプロセスが終了するまで、 プロセスを立ち上げたスレッドを停止させておく ことはまずいですか?
- magicalpass
- ベストアンサー率58% (378/648)
参照先のソースでは、セマフォの生成はスレッドの生成元で行ってますが、セマフォによる制御は生成されたスレッド側で行ってますが、ここに記載されたソースではすべてプロセスの生成元で行ってるのは何故ですか? 自分でセマフォを作って、自分にセマフォによる制御を掛けてるのはおかしくないですか? あと、注意する点としては、サンプルで使われてる名前なしのセマフォは同一プロセス内でしか使えません。同一プロセス内でスレッドの制御に使うのは構いませんが、別プロセスを生成した制御は出来ません。プロセス間で有効にするにはきちんと名前をつけましょう。
補足
ご回答、有難うございます。 (返信、遅れてすみません。) > 自分でセマフォを作って、自分にセマフォによる制御を掛けてるのはおかしくないですか? 参照したホームページでは、呼び出されたスレッドの内部でセマフォをリリース しています。 今回の場合、既存外部プログラム(プロセス)を呼びたいと考えています。 そうすると、その外部プログラムには修正を加えることでできないため、 呼び出し元のソースにセマフォのリリースのコードも書いてしまいました。 外部プログラムをセマフォで制御する方法には、どうしたらよいでしょうか。 また、名前をつける理由が分かりました。 有難うございました。
補足
ご回答、有難うございます。 理解できした。 プロセスの一時停止、再開は別の質問として 改めて尋ねようと思います。