Запускать приложение постоянно

Какой самый разумный способ непрерывно запускать приложение, чтобы оно не выходило после того, как достигло дна? Вместо этого он запускается снова сверху основного и завершается только по команде. (Это в C)

Ответов (4)

Решение

У вас всегда должен быть какой-то способ аккуратного выхода. Я бы предложил перенести код в другую функцию, которая возвращает флаг, чтобы сказать, выходить или нет.

int main(int argc, char*argv[])
{

     // param parsing, init code

     while (DoStuff());

    // cleanup code
    return 0;
 }

 int DoStuff(void)
 {
     // code that you would have had in main

     if (we_should_exit)
         return 0;

     return 1;
 }

Существует несколько способов «дать команду» вашему приложению выйти (например, с помощью глобального флага выхода или кодов возврата). Некоторые уже коснулись использования кода выхода, поэтому я предлагаю простую модификацию, которую можно внести в существующую программу с помощью флага выхода.

Предположим, ваша программа выполняет системный вызов для вывода списка каталогов (полный каталог или отдельный файл):

int main (int argCount, char *argValue[]) {
    char *cmdLine;
    if (argCount < 2) {
        system ("ls");
    } else {
        cmdLine = malloc (strlen (argValue[1]) + 4);
        sprintf (cmdLine, "ls %s", argValue[1]);
        system (cmdLine);
    }
}

Как нам сделать этот цикл до условия выхода. Выполняются следующие шаги:

  • Измените main()на oldMain().
  • Добавить новый exitFlag.
  • Добавить новый main()для непрерывного вызова, oldMain()пока не будет отмечен выход.
  • В oldMain()какой-то момент изменится на выход по сигналу.

Это дает следующий код:

static int exitFlag = 0;

int main (int argCount, char *argValue[]) {
    int retVal = 0;

    while (!exitFlag) {
        retVal = oldMain (argCount, argValue);
    }

    return retVal;
}

static int oldMain (int argCount, char *argValue[]) {
    char *cmdLine;
    if (argCount < 2) {
        system ("ls");
    } else {
        cmdLine = malloc (strlen (argValue[1]) + 4);
        sprintf (cmdLine, "ls %s", argValue[1]);
        system (cmdLine);
    }

    if (someCondition)
        exitFlag = 1;
}

Большинство приложений, которые не проваливаются, входят в какой-то цикл обработки событий, который позволяет программировать, управляемое событиями.

Например, при разработке Win32 вы должны написать свою функцию WinMain для непрерывной обработки новых сообщений, пока она не получит сообщение WM_QUIT, сообщающее приложению о завершении. Этот код обычно имеет следующую форму:

// ...meanwhile, somewhere inside WinMain()
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
     TranslateMessage(&msg);
     DispatchMessage(&msg);
}

Если вы пишете игру с использованием SDL , вы будете зацикливаться на событиях SDL до тех пор, пока не решите выйти, например, когда вы обнаружите, что пользователь нажал клавишу Esc. Некоторый код для этого может напоминать следующий:

bool done = false;
while (!done)
{
    SDL_Event event;
    while (SDL_PollEvent(&event))
    {
        switch (event.type)
        {
            case SDL_QUIT:
                done = true;
                break;
            case SDL_KEYDOWN:
                if (event.key.keysym.sym == SDLK_ESCAPE)
                {
                    done = true;
                }
                break;
        }
    }
}

Вы также можете прочитать о демонах Unix и службах Windows .

while (true)
{
....
}

Чтобы уточнить немного больше, вы хотите поместить что-то в этот цикл, что позволит вам позволить пользователю выполнять повторяющиеся действия. Будь то чтение нажатий клавиш и выполнение действий на основе нажатых клавиш или чтение данных из сокета и отправка ответа.