Я разрабатываю программу на C ++, и было бы полезно использовать какую-то функцию, скрипт или что-то, что заставляет программу перезапускаться. Это большая программа, поэтому перезапуск всех переменных вручную займет у меня много времени …
Я не знаю, есть ли способ достичь этого или это возможно.
Если вам действительно нужно перезапустить всю программу (то есть снова «закрыть» и «открыть»), то «правильным» способом будет иметь отдельную программу с единственной целью перезапустить вашу основную. AFAIK многие приложения с функцией автообновления работают таким образом. Поэтому, когда вам нужно перезапустить основную программу, вы просто вызываете «перезапуск» и выходите.
Вы можете использовать цикл в вашем main
функция:
int main()
{
while(!i_want_to_exit_now) {
// code
}
}
Или, если вы действительно хотите перезапустить программу, запустите ее из жгута:
program "$@"while [ $? -e 42 ]; do
program "$@"done
где 42
код возврата, означающий «перезагрузите, пожалуйста».
Тогда внутри программы ваш restart
функция будет выглядеть так:
void restart() {
std::exit(42);
}
На Unicies или где-либо еще у вас есть execve
и это работает как страница руководства указывает, ты можешь просто …убей меня за использование atoi
потому что это вообще ужасно, за исключением такого рода случая.
#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;
}
Пример:
$ ./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 был код возврата).
Он ни рекурсивно, ни явно не зацикливается — вместо этого он просто вызывает себя, заменяя свое собственное пространство памяти новой версией самого себя.
Таким образом, стек никогда не будет переполнен, хотя все предыдущие переменные будут переопределены, как и при любой повторной вызове — getchar
вызов предотвращает 100% загрузку процессора.
В случае самообновляющегося двоичного файла, поскольку весь двоичный файл (по крайней мере, для Unix-подобных, я не знаю о Windows) будет скопирован в память во время выполнения, то, если файл изменяется на диске до execve(argv[0], ...
вызов, вместо этого будет запущен новый двоичный файл, найденный на диске, а не тот же самый старый.
Как отмечают @CarstenS и @bishop в комментариях, благодаря уникальному способу разработки Unix дескрипторы открытых файлов сохраняются fork
/exec
и, как следствие, во избежание утечки открытых файловых дескрипторов при обращении к execve
, вы должны либо закрыть их раньше execve
или открыть их с помощью e
, FD_CLOEXEC
/ O_CLOEXEC
в первую очередь — больше информации можно найти на Блог Дэна Уолша.
Это очень специфичный для ОС вопрос. В Windows вы можете использовать API перезапуска приложений или же MFC Restart Manager. В Linux вы могли бы сделать exec()
Однако в большинстве случаев есть лучшее решение. Скорее всего, вам лучше использовать цикл, как предлагается в других ответах.
Это звучит как неправильный подход, так как все ваше состояние является глобальным, и поэтому единственный четкий метод сброса всего (кроме ручного назначения значений «по умолчанию» для каждой переменной) — это перезапуск всей программы.
Вместо этого ваше состояние должно храниться в объектах (типа класса или чего-либо еще). Тогда вы можете создавать и уничтожать эти объекты в любое время. Каждый новый объект имеет новое состояние со значениями по умолчанию.
Не боритесь с C ++; используй это!
Вам, вероятно, нужен цикл:
int main()
{
while (true)
{
//.... Program....
}
}
Каждый раз, когда вам нужно перезагрузить, звоните continue;
в цикле, и чтобы завершить вашу программу, используйте break;
,
Когда я разрабатываю системы реального времени, мой подход обычно является «производным main ()», где я пишу весь код, вызываемый из реального main (), что-то вроде:
Программа main.cpp:
int main (int argc, char *argv[])
{
while (true)
{
if (programMain(argc, argv) == 1)
break;
}
}
Программа main.cpp, где написан весь код:
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;
}
Таким образом, каждый раз, когда мы решаем выйти из программы, программа будет перезапущена.
Подробно: все переменные, глобалы и логика должны быть записаны внутри programMain()
— ничего внутри "main()"
кроме перезапуска управления.
Этот подход работает в системах Linux и Windows.
Мне кажется, что вы задаете неправильный вопрос, потому что вы недостаточно знаете о кодировании, чтобы задать правильный вопрос.
Звучит так, будто вы спрашиваете, как написать некоторый код, при котором при пропущенном вызове он возвращается к исходному состоянию и перезапускает всю последовательность вызова / местоположения. В этом случае вам нужно использовать Государственный аппарат. Посмотрите, что это такое, и как написать. Это ключевая концепция программного обеспечения, и вы должны знать, если ваши учителя хорошо справляются со своей работой.
В качестве дополнительного примечания: если вашей программе для инициализации всех ваших переменных требуется 5 с, по-прежнему потребуется 5 с, когда вы перезапустите ее. Вы не можете сократить это. Итак, из этого должно быть ясно, что вы не на самом деле хотите убить и перезапустить вашу программу, потому что тогда вы получите именно то поведение, которое вам не нужно. С помощью конечного автомата вы можете иметь одно состояние инициализации для холодного запуска, когда система только что была включена, и второе состояние инициализации для горячего перезапуска.
Ох и 6 тем не очень много! 🙂