Estoy tratando de generar un nuevo proceso de mi proyecto C++ - usando fork-exec. Estoy utilizando fork-exec para crear un conducto bidireccional para el proceso secundario. Pero me temo que mis recursos en el proceso bifurcado no se liberarán correctamente, ya que la llamada ejecutiva asumirá completamente mi proceso y no va a llamar a ningún destructor.Liberando recursos de C++ y fork-exec?
Intenté eludir esto lanzando una excepción y llamando a execl desde un bloque catch al final de main, pero esta solución no destruye ningún singletons.
¿Hay alguna manera sensata de lograr esto de forma segura? (Esperemos evitando cualquier hacks atexit)
Ex: Las siguientes salidas de código:
We are the child, gogo!
Parent proc, do nothing
Destroying object
A pesar de que el proceso de horquilla también tiene una copia del singleton que debe ser destruido antes de que llame 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;
}
¿De qué recursos estás hablando? La mayoría de las descripciones de archivos sobreviven a exec(), que puede marcar close-on-exec para que el kernel las cierre por usted. http://pubs.opengroup.org/onlinepubs/009695399/functions/exec.html –
Por cierto, si se llamaran a los destructores tanto en el hijo bifurcado como en el padre, terminaría llamando a los constructores una vez (en el padre) y destructores dos veces (tanto en el padre como en el hijo). –
Creo que me estoy acercando peligrosamente al comportamiento indefinido aquí, pero la clase Resources representa varias clases singleton que utilizo para envolver bibliotecas C en objetos RAII. Y si fork realmente copia todo el estado del proceso, probablemente debería llamar a RAII-destructores antes de llamar a exec(). Esto, por supuesto, sería una locura si los recursos fueran externos al programa (como una conexión de base de datos). Pero dado que son bibliotecas, creo que deberían publicarse tanto en el proceso principal como en el secundario. [Si me sirve, estoy actualizando ncurses, nscapi y SDL en singletons] – Phog