Я пытаюсь создать новый процесс из моего проекта на C++, используя fork-exec. Я использую fork-exec для создания двунаправленного канала для дочернего процесса. Но я боюсь, что мои ресурсы в разветвленном процессе не будут освобождены должным образом, так как exec-call полностью захватит мой процесс и не назовет каких-либо деструкторов.Освобождение ресурсов C++ и fork-exec?
Я попытался обойти это, выбросив исключение и вызвав execl из блока catch в конце main, но это решение не уничтожает ни одного синглтона.
Есть ли разумный способ достичь этого безопасно? (Надеюсь, избегая atExit хаков)
Пример: Следующий код выводит:
We are the child, gogo!
Parent proc, do nothing
Destroying object
Несмотря на то, раздвоенный процесс также имеет копию синглтона, которая должна быть уничтожена, прежде чем я называю execl.
#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(), которые вы можете отметить close-on-exec, чтобы ядро их закрыло. http://pubs.opengroup.org/onlinepubs/009695399/functions/exec.html –
Кстати, если деструкторы были вызваны в разветвленном дочернем, а также в родительском, это приведет к вызову конструкторов один раз (в родительском) и деструкторы дважды (как в родительском, так и в дочернем). –
Я считаю, что здесь опасно приближается к неопределенному поведению, но класс Resources представляет несколько одноэлементных классов, которые я использую для обертывания C-библиотек в RAII-объекты. И если fork действительно копирует все состояние процесса, я должен, вероятно, вызвать RAII-деструкторы, прежде чем я вызову exec(). Разумеется, это было бы безумным, если бы ресурсы были внешними по отношению к программе (например, соединение с базой данных). Но поскольку они являются библиотеками, я считаю, что они должны быть выпущены как в родительском, так и в дочернем процессе. [Если это помогает, я в настоящее время обертываю ncurses, nscapi и SDL в singleletons] – Phog