es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

El destructor del objeto asignado en la pila no se llama cuando el programa es finalizado desde la terminal.

He escrito una aplicación de línea de comandos corta que utiliza una biblioteca para realizar algunas comunicaciones en red. La biblioteca de comunicación en red debe inicializarse antes de su uso y tiene una función de destrucción que debe llamarse para que la pila de red se desmonte correctamente cuando la aplicación finaliza.

class NetworkTester
{
public:
    NetworkTester()
    {
        cout << "Creando NetworkStack" << endl;
        NetworkStack::create();
        reader = new NetworkReader();
    }
    ~NetworkTester()
    {
        cout << "Destruyendo NetworkStack" << endl;
        delete reader;
        NetworkStack::destroy();
    }
    void poll()
    {
        Duration waitTime = MillisecondsDuration(1 * 1000);
        while (reader->read(networkData, waitTime))
        {
            // hacer algo
        }
    }
private:
    NetworkReader * reader;
    NetworkData networkData {};
};

int main(int argc, char ** argv)
{
    NetworkTester tester {};

    while(1)
    {
        // hacer algo
    }

    return 1;
}

Sin embargo, estoy teniendo problemas con esto, ya que cuando uso ctrl+c para enviar una señal SIGINT al proceso y así terminarlo, el destructor de NetworkTester no se está llamando. Esto significa que mi NetworkReader asignado dinámicamente no se está liberando y, lo que es más importante, NetworkStack::Destroy no se está llamando. Esto hace que la pila de red falle al inicializarse correctamente la próxima vez que se use.

He probado mi destructor creando un objeto en un ámbito y viendo la salida del destructor, así que estoy bastante seguro de que mi código destructor está bien.

Lo que me gustaría entender es qué está sucediendo cuando el programa recibe SIGINT y por qué las variables en la pila no se destruyen correctamente – ¿alguien tiene alguna idea al respecto?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Parece que el problema es que cuando el programa recibe una señal SIGINT, provoca una terminación anormal del programa, lo que evita el desenrollado normal de la pila que ocurre durante una terminación regular del programa. Esto significa que el destructor de NetworkTester no está siendo llamado y, por lo tanto, NetworkStack::destroy tampoco está siendo llamado.

    Una posible solución a este problema es registrar un manejador de señales para SIGINT utilizando la función signal() en C++. Dentro de la función del manejador de señales, puedes llamar al destructor de NetworkTester manualmente para asegurarte de que se realice la limpieza necesaria antes de que el programa se cierre abruptamente.

    Otra solución podría ser utilizar RAII (Resource Acquisition Is Initialization) para garantizar que NetworkStack se cree y destruya automáticamente de una manera que sea inmune a excepciones durante el desenrollado de la pila, como ocurre durante una señal SIGINT. Esto implicaría envolver la clase NetworkStack en una clase separada que cree una instancia de NetworkStack en su constructor y luego llame a la función destroy en su destructor. De esta manera, la destrucción del objeto NetworkStack está garantizada de ocurrir independientemente de cómo termine el programa.

Comments are closed.