Sto provando a generare un nuovo processo dal mio progetto C++ usando fork-exec. Sto usando fork-exec per creare un pipe bidirezionale per il processo figlio. Ma temo che le mie risorse nel processo forked non vengano liberate correttamente, dal momento che la chiamata exec prenderà completamente il mio processo e non chiamerà alcun distruttore.Rilascio di risorse C++ e fork-exec?
Ho tentato di aggirare questo problema lanciando un'eccezione e chiamando execl da un blocco catch alla fine del main, ma questa soluzione non distrugge alcun singletons.
Esiste un modo ragionevole per raggiungere questo obiettivo in sicurezza? (Si spera evitando qualsiasi hack AtExit)
Es: le seguenti uscite codice:
We are the child, gogo!
Parent proc, do nothing
Destroying object
Anche se il processo biforcuta ha anche una copia del singleton che deve essere distrutti prima che chiami 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;
}
Di quali risorse stai parlando? Principalmente i descrittori di file sopravvivono a exec(), che è possibile contrassegnare close-on-exec in modo che il kernel li chiuda per te. http://pubs.opengroup.org/onlinepubs/009695399/functions/exec.html –
A proposito, se i distruttori venivano chiamati sia nel bambino biforcuto che nel genitore, finiva per chiamare i costruttori una volta (nel genitore) e distruttori due volte (sia nel genitore che nel bambino). –
In questo caso, mi sto avvicinando pericolosamente al comportamento non definito, ma la classe Resources rappresenta diverse classi singleton che utilizzo per il wrapping di librerie C in oggetti RAII. E se fork copia davvero l'intero stato del processo, allora probabilmente dovrei chiamare i distruttori RAII prima di chiamare exec(). Questo sarebbe ovviamente folle se le risorse fossero esterne al programma (come una connessione al database). Ma dal momento che sono biblioteche, credo che dovrebbero essere rilasciati sia nel processo genitore che in quello secondario. [Se aiuta, sto attualmente inserendo ncurses, nscapi e SDL in singleton] – Phog