1

エグゼクティブサマリー:_spawnlを介して生成し、_pipeからFDを使用して通信しているWindowsプロセスが停止したかどうかを判断する方法が必要です。

詳細:

Windowsの低レベルCRT関数(_eof、_read)を使用して、(P_NOWAITを使用した)_spawnlの呼び出しを介して生成されたプロセスと通信しています。_pipeを使用して、この生成されたプロセスと通信するファイル記述子を作成し、それらの記述子(FD#)をコマンドラインで渡します。

スポーンされたプロセスを制御していないことは言及する価値があります。それは私にとってブラックボックスです。

スポーンしているプロセスがときどきクラッシュすることがわかりました。クラッシュを検出することで、コードをこれに対して堅牢にしようとしています。残念ながら、これを行う方法がわかりません。プロセスが停止した場合、これらの記述子の1つで_eofまたは_readを呼び出すと、エラーステータス(-1)が返されると予想するのは妥当なようです。

残念ながら、そうではありません。記述子には、生成されたプロセスとは独立した独自の寿命があるようです。そのため、もう一方のプロセスが停止していても、通信に使用しているファイル記述子にエラーステータスは表示されません。

ネストされたプロセス(_spanwnl呼び出しから返される)のPIDを取得しましたが、それを使用して実行できることは何も表示されません。私のコードは、1つを除いて本当にうまく機能します。生成されたプロセスが単に答えを計算するのに忙しいのか、それとも死んだのかを検出できません。

_pipeと_spawnlからの情報を使用して、生成されたプロセスが停止しているかどうかを判断できれば、私は金色になります。

提案は大歓迎です。

前もって感謝します。

更新:私はかなり単純な解決策を見つけ、それを選択された答えとして追加しました。

4

3 に答える 3

1

プロセスが終了したことを検出できるようにするには、食物連鎖を上に移動する必要があります。ネイティブのCreateProcess()Win32 APIは、ハンドルを返すことができます。これをWaitForSingleObject()APIで使用して、プロセスが終了したかどうかを待機またはテストできます。PIDを取得できる場合は、OpenProcess()を使用して必要なHANDLEを取得できます。

もう1つのアプローチは、_P_WAITを使用して同期呼び出しを行うことです。それにはスレッドが必要になります。

于 2010-01-22T20:18:38.753 に答える
1

Windowsで子プロセスのステータスとリソースの使用状況を知る方法を参照 してください。

spawnlから返されたハンドルでWaitForSingleObjectを使用できます。それは私にとってはうまく機能しています。あなたはすでにこれを試したようですが、おそらく私はあなたの反応を誤解しています。

プロセスを生成し、_P_WAITを使用せずにプロセスが終了するのを待つサンプルコード:

HANDLE hProcess = (HANDLE) _spawnl(_P_NOWAIT, "slave.exe", "slave.exe", NULL);
while(1)
{
  Sleep(100);
  if (WaitForSingleObject(hProcess, 0) == WAIT_OBJECT_0)
  {
    break;
  }
}
于 2010-04-09T16:48:38.103 に答える
0

たくさんの良いアドバイスをしてくれたnobugzに感謝します。私は彼の「食物連鎖を上る」というルートをとることにならなかったので、これを別の答えとして書いていますが、それは彼のフィードバックの結果です。

私はspawnlに既存の呼び出しを使用しました。P_NOWAITモードで呼び出された場合、戻り値は実際にはOpenProcessと同じであるため、これが可能であることがわかりました。spawnlの戻りタイプはintptr_tであるのに対し、OpenProcessの戻りタイプはHANDLEであるため、これは混乱を招きます。しかし、それらは同等です(少なくとも私のテストに基づくと)。

これを知って、私はまだ森から出ていませんでした。プロセスがまだ実行されているかどうかを判断するための信頼できる方法が必要でした。プロセスハンドル(GetModuleBaseNameなど)を使用して行ったさまざまな呼び出しはすべて、プロセスが停止している場合でも成功しました。

最終的に、(プロセスハンドルを使用して)GetProcessIdを呼び出してプロセスIDを取得し、次にEnumerateProcessesを呼び出して、そこから返された結果を調べて、実行中のプロセスのいずれかが同じプロセスIDを共有しているかどうかを確認しました。

(nobugzが提案したように)より高いレベルのAPIを使用することが、おそらく一般的な方法であることを認めます。私の場合、すでにすべてのコードが機能していて、ネストされたプロセスがまだ実行されているかどうかを判断するだけでよいので、最小限のアプローチを採用しました。

すべての有益な提案をしてくれたnobugzに改めて感謝します。

于 2010-01-25T21:52:53.460 に答える