Sur Unicies, ou n'importe où ailleurs, vous avez execve
et cela fonctionne comme la page de manuel précise vous pouvez juste... me tuer pour avoir utilisé <code>atoi</code> parce que c'est généralement horrible, sauf pour ce genre de cas.
#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;
}
Exemple :
$ ./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 était le code de retour).
Il ne récure ni ne boucle explicitement - au lieu de cela, il s'appelle lui-même, remplaçant son propre espace mémoire par une nouvelle version de lui-même.
De cette manière, la pile ne débordera jamais, bien que toutes les variables précédentes soient redéclarées, comme lors de toute réinvocation -- la fonction getchar
empêche une utilisation à 100% du CPU.
Dans le cas d'un binaire auto-actualisé, puisque le binaire entier (du moins, sur les systèmes Unix, je ne sais pas pour Windows) sera copié en mémoire au moment de l'exécution, alors si le fichier change sur le disque avant que la commande execve(argv[0], ...
le nouveau binaire trouvé sur le disque, et non le même ancien, sera exécuté à la place.
Comme @CarstenS et @bishop le soulignent dans les commentaires, en raison de la manière unique dont Unix a été conçu, les descripteurs de fichiers ouverts sont conservés dans tous les fichiers de la base de données. fork
/ exec
et, par conséquent, afin d'éviter les fuites de descripteurs de fichiers ouverts entre les appels à la fonction execve
vous devez soit les fermer avant execve
ou les ouvrir avec e
, FD_CLOEXEC
/ O_CLOEXEC
en premier lieu -- plus d'informations peuvent être trouvées sur Le blog de Dan Walsh .
40 votes
Quoi que vous fassiez, n'appelez pas
main()
dans votre code.15 votes
"redémarrer toutes les variables manuellement" Wut ?
5 votes
Avez-vous envisagé d'utiliser une boucle ?
1 votes
Le programme a 6 fils, donc il n'est pas petit
8 votes
Quelle plateforme ? Si c'est quelque chose qui ressemble de près ou de loin à POSIX, vous pourriez vouloir regarder dans la section
exec()
famille de fonctions.1 votes
Pour quel système d'exploitation ? De nombreux systèmes d'exploitation vous permettent d'exécuter une nouvelle image de programme dans le processus actuel, ce qui peut inclure la ré-exécution du processus actuel.
2 votes
Quel est votre objectif en relançant le programme ? Que voulez-vous accomplir ? Cela peut vous aider à déterminer la meilleure façon de redémarrer votre application.
4 votes
Vous êtes peut-être dans une région sensible. Voulez-vous a) "Développer un programme qui est conscient que vous pouvez vouloir 'redémarrer' en réinitialisant son état à un endroit proche du début du programme" ou b) "Frapper le programme existant sur la tête et redémarrer pendant qu'il ne regarde pas ? Dans un programme multi-filière, la première solution nécessite une grande attention aux détails. La seconde peut être extrêmement dangereuse en fonction de ce que font les threads à ce moment-là.
1 votes
Et si on utilisait simplement une boucle ? Tant que vous n'utilisez pas de globales que vous pouvez modifier, tout ira bien.
36 votes
Cela ressemble à un Problème XY .
1 votes
C'est Linux, qui fonctionne sur une carte Raspberry Pi. C'est le système embarqué d'un train qui localise le train (IMU, GPS, modem GSM/GPRS) et qui doit être redémarré après avoir reçu un appel manqué.
4 votes
En tant que personne ayant une certaine expérience de l'industrie ferroviaire, cette question m'effraie un peu. À propos, votre application pourrait peut-être bénéficier d'être rédigée en Erlang plutôt que C++, car Erlang était littéralement créé pour la téléphonie tolérante aux pannes .
2 votes
Ce que je développe n'est qu'un prototype, il ne sera donc pas mis en œuvre dans un train à des fins commerciales. Il fait partie d'un projet de recherche.
2 votes
Cela ressemble au genre de chose qu'un démon chien de garde a été inventé (et vérifiez si vous avez un chien de garde matériel, pour permettre un redémarrage complet du système si nécessaire).