while volver reiniciar regresar punto programa preguntar lenguaje inicio empezar como c++ application-restart

volver - regresar al inicio del programa c++



¿Es posible reiniciar un programa desde dentro de un programa? (9)

Estoy desarrollando un programa C ++ y sería útil usar alguna función, script o algo que haga que el programa se reinicie. Es un programa grande, así que reiniciar todas las variables manualmente me llevará mucho tiempo ...

No sé si hay alguna forma de lograrlo o si es posible.


Cuando desarrollo sistemas en tiempo real, mi enfoque es normalmente un "main () derivado" donde escribo todo el código llamado desde un main principal (), algo como:

El programa main.cpp:

int main (int argc, char *argv[]) { while (true) { if (programMain(argc, argv) == 1) break; } }

El programmain.cpp, donde se escribe todo el código:

int programMain(int argc, char *argv[]) { // Do whatever - the main logic goes here // When you need to restart the program, call return 0; // When you need to exit the program, call return 1; }

De esa manera, cada vez que decidamos salir del programa, el programa se reiniciará.

Detalle: todas las variables, variables globales y lógica deben escribirse dentro de programMain() - nada dentro de "main()" excepto el control de reinicio.

Este enfoque funciona tanto en sistemas Linux como Windows.


Dependiendo de lo que quiere decir con "reiniciar" el programa, puedo ver algunas soluciones simples.

Una es incrustar todo el programa en alguna clase de "Programa", que esencialmente proporciona un bucle que tiene su programa adecuado. Cuando necesite reiniciar el programa, debe llamar al método público estático "Reiniciar" que inicia el ciclo nuevamente.

También puede intentar realizar una llamada específica del sistema que inicie nuevamente su programa y salir. Como se sugiere en otra respuesta, puede crear un programa de envoltorio para este único propósito (y verificar el código de retorno para saber si debe salir o reiniciar).

La otra opción simple es usar goto . Sé que la gente me odiará incluso por mencionarlo, pero seamos sinceros: queremos hacer un programa simple, no usar una placa de caligrafía hermosa. Ir hacia atrás garantiza la destrucción , por lo que podría crear un programa con una etiqueta al principio y alguna función "Reiniciar" que solo se remonta al principio.

Cualquiera que sea la opción que elija, documéntela bien, para que otros (o usted en el futuro) utilicen un WTF menos.

PD. Como lo mencionó alain , goto no destruirá los objetos globales ni los estáticos, lo mismo sucedería para encerrar a la clase. Por lo tanto, cualquier enfoque que no incluya iniciar un nuevo programa en lugar del actual debería abstenerse de usar variables globales / estáticas, o tomar las medidas adecuadas para restablecerlas (aunque eso puede ser tedioso, como con la adición de cada una de las funciones estáticas / globales). , necesitas modificar la rutina de reinicio).


En Unicies, o en cualquier otro lugar que tengas execve y funciona como lo especifica la página de manual , puedes ... matarme por usar atoi , porque en general es horrible, excepto en este tipo de casos.

#include <unistd.h> #include <stdio.h> #include <stdlib.h> int main (int argc, char** argv) { (void) argc; printf("arg: %s/n", argv[1]); int count = atoi(argv[1]); if ( getchar() == ''y'' ) { ++count; char buf[20]; sprintf(buf, "%d", count); char* newargv[3]; newargv[0] = argv[0]; newargv[1] = buf; newargv[2] = NULL; execve(argv[0], newargv, NULL); } return count; }

Ejemplo:

$ ./res 1 arg: 1 y arg: 2 y arg: 3 y arg: 4 y arg: 5 y arg: 6 y arg: 7 n 7 | $

(7 era el código de retorno).

No recurre ni se desplaza explícitamente, sino que se llama a sí mismo, reemplazando su propio espacio de memoria con una nueva versión de sí mismo.

De esta manera, la pila nunca se desbordará, aunque todas las variables anteriores se volverán a declarar, al igual que con cualquier reinvocación: la llamada a getchar evita el 100% de utilización de la CPU.

En el caso de un binario que se actualiza automáticamente, ya que todo el binario (al menos, en Unix-likes, no sé acerca de Windows) se copiará en la memoria en tiempo de ejecución, luego si el archivo cambia en el disco antes del execve(argv[0], ... call, el nuevo binario que se encuentra en el disco, no el mismo antiguo, se ejecutará en su lugar.

Como @CarstenS y @bishop señalan en los comentarios, debido a la forma única en que se diseñó Unix, los descriptores de archivos abiertos se mantienen en fork / exec , y como resultado para evitar la pérdida de descriptores de archivos abiertos a través de llamadas a execve , Debería cerrarlos antes de execve o abrirlos con e , FD_CLOEXEC / O_CLOEXEC en primer lugar. Puede encontrar más información en el blog de Dan Walsh .


Esta es una pregunta muy específica del sistema operativo. En Windows puede usar la API de reinicio de la aplicación o el administrador de reinicio de MFC . En Linux puedes hacer un exec()

Sin embargo la mayor parte del tiempo hay una mejor solución. Probablemente sea mejor usar un bucle, como se sugiere en otras respuestas.


Esto suena como un enfoque equivocado, como si todo su estado fuera global y, por lo tanto, el único método claro que tiene para restablecer todo (además de asignar manualmente valores "predeterminados" a cada variable) es reiniciar todo el programa.

En su lugar, su estado debe mantenerse en objetos (de tipo de clase, o lo que sea). Entonces, eres libre de crear y destruir estos objetos cuando quieras. Cada nuevo objeto tiene un estado nuevo con valores "predeterminados".

No luches contra C ++; úsalo!


Me parece que estás haciendo la pregunta incorrecta porque no sabes lo suficiente acerca de la codificación para hacer la pregunta correcta.

Lo que parece que estás preguntando es cómo escribir un código donde, en una llamada perdida, vuelve al estado inicial y reinicia toda la secuencia de llamadas / ubicación. En cuyo caso necesitas usar una máquina de estados . Mira lo que es eso, y cómo escribir uno. Este es un concepto de software clave, y debes saberlo si tus maestros fueron buenos en su trabajo.

Como nota al margen, si su programa tarda 5s en inicializar todas sus variables, seguirá tomando 5s cuando lo reinicie. No puedes atajar eso. Por lo tanto, debe quedar claro que en realidad no desea matar y reiniciar su programa, porque entonces obtendrá exactamente el comportamiento que no desea. Con una máquina de estados, puede tener un estado de inicialización para el arranque en frío donde el sistema se acaba de encender, y un segundo estado de inicialización para un reinicio en caliente.

¡Oh, y 6 hilos no son muchos! :)


Probablemente necesitas un bucle:

int main() { while (true) { //.... Program.... } }

Cada vez que necesites reiniciar, llama a continue; dentro del bucle, y para finalizar tu programa, usa break; .


Puedes usar un bucle en tu función main :

int main() { while(!i_want_to_exit_now) { // code } }

O, si desea reiniciar el programa, ejecútelo desde un arnés:

program "$@" while [ $? -e 42 ]; do program "$@" done

donde 42 es un código de retorno que significa "reiniciar, por favor".

Luego, dentro del programa, su función de restart se vería así:

void restart() { std::exit(42); }


Si realmente necesita reiniciar todo el programa (es decir, para "cerrar" y "abrir" nuevamente), la forma "adecuada" sería tener un programa separado con el único propósito de reiniciar el programa principal. AFAIK muchas aplicaciones con función de actualización automática funcionan de esta manera. Así que cuando necesite reiniciar su programa principal, simplemente llame al "reinicio" y salga.