C++プロジェクトからfork-execを使用して新しいプロセスを生成しようとしています。子プロセスへの双方向パイプを作成するためにfork-execを使用しています。しかし、エグゼクティブコールがプロセスを完全に引き継いでデストラクタを呼び出さないため、フォークされたプロセスのリソースが適切に解放されないことは恐れられます。C++リソースとfork-execを解放しますか?
私は例外をスローし、execlをmainの最後のcatchブロックから呼び出すことでこれを回避しようとしましたが、この解決法はシングルトンを破壊しません。
これを安全に達成するための賢明な方法はありますか?
例(うまくいけば任意のATEXITハックの回避):次のコード出力:
フォークプロセスはまた、私はEXECLを呼び出す前に破壊する必要がシングルトンのコピーを持っているにもかかわらずWe are the child, gogo!
Parent proc, do nothing
Destroying object
。
#include <iostream>
#include <unistd.h>
using namespace std;
class Resources
{
public:
~Resources() { cout<<"Destroying object\n"; }
};
Resources& getRes()
{
static Resources r1;
return r1;
}
void makeChild(const string &command)
{
int pid = fork();
switch(pid)
{
case -1:
cout<<"Big error! Wtf!\n";
return;
case 0:
cout<<"Parent proc, do nothing\n";
return;
}
cout<<"We are the child, gogo!\n";
throw command;
}
int main(int argc, char* argv[])
{
try
{
Resources& ref = getRes();
makeChild("child");
}
catch(const string &command)
{
execl(command.c_str(), "");
}
return 0;
}
あなたはどのリソースについて話していますか?ほとんどのファイル記述子はexec()に残っています。exec()はclose-on-execをマークして、カーネルがそれらを閉じることができます。 http://pubs.opengroup.org/onlinepubs/009695399/functions/exec.html –
ちなみに、デストラクタが分岐した子や親の中で呼び出された場合、デストラクタは一度(親)とデストラクタを2回(親と子の両方で)実行します。 –
私はここでは未定義の挙動に危険なほど近いと思っていますが、ResourcesクラスはCライブラリをRAIIオブジェクトにラッピングするために使用するいくつかのシングルトンクラスを表しています。そして、forkが実際にプロセスの状態全体をコピーするならば、私はexec()を呼び出す前におそらくRAIIデストラクタを呼び出すべきです。もちろん、リソースがプログラムの外部(データベース接続のようなもの)であった場合、これは狂気になります。しかし、彼らは図書館なので、私は彼らが親プロセスと子プロセスの両方でリリースされるべきだと考えています。 [役立つなら、現在はncurses、nscapi、SDLをシングルトンにラップしています] – Phog