Ответ 1
Вы можете и, вероятно, должны добавить обработчик вывода, если ваш код будет использоваться другими людьми, или вы сами просто хотите его очистить. В вашем обработчике вы можете переключить флаг, который завершает цикл while()
. Следующий код будет работать на 100% штрафом для этого варианта использования и является надежным и кросс-платформенным, но если вы хотите делать более сложные вещи, вы должны использовать надлежащие поточные операционные функции, определенные ОС, или что-то вроде Boost или С++ 11
Сначала объявите две глобальные переменные, сделайте их volatile, чтобы компилятор всегда заставлял нас читать или записывать его фактическое значение памяти. Если вы не объявите его volatile, тогда возможно, что компилятор может поместить его значение в регистр, который сделает это неработоспособным. С помощью volatile set он будет считывать местоположение памяти в каждом цикле и работать правильно, даже с несколькими потоками.
volatile bool bRunning=true;
volatile bool bFinished=false;
и вместо вашего цикла while(1) {}
измените его на
while(bRunning)
{
dostuff
}
bFinished=true;
В вашем обработчике вы просто установите bRunning=false;
void ExitHandler()
{
bRunning=false;
while(bFinished==false) { Sleep(1); }
}
Вы не указали операционную систему, но похоже, что вы основаны на Linux, для установки обработчика на Linux вам это нужно.
void ExitHandler(int s)
{
bRunning=false;
}
int main()
{
struct sigaction sigIntHandler;
sigIntHandler.sa_handler = ExitHandler;
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
sigaction(SIGINT, &sigIntHandler, NULL);
while(bRunning)
{
dostuff
}
...error_handling...
}
И в Windows, когда вы являетесь консольным приложением, это следующее.
BOOL WINAPI ConsoleHandler(DWORD CEvent)
{
switch (CEvent)
{
case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
bRunning = false;
while (bFinished == false) Sleep(1);
break;
}
return TRUE;
}
int main()
{
SetConsoleCtrlHandler(ConsoleHandler, TRUE);
while(bRunning()
{
dostuff
}
...error_handling...
}
Обратите внимание на необходимость тестирования и ожидания bFinished
здесь. Если вы не сделаете этого в Windows, ваше приложение может не иметь достаточно времени для выключения, поскольку обработчик выхода вызывается отдельным потоком конкретной ОС. В Linux это не обязательно, и вам нужно выйти из вашего обработчика для основного потока, чтобы продолжить.
Еще одна вещь, которую стоит отметить: по умолчанию Windows только дает вам ~ 5 секунд, чтобы закрыть ее, прежде чем она вас прекратит. Это во многих случаях является неудачным, и если требуется больше времени, вам нужно будет изменить настройку реестра (плохая идея) или реализовать службу, которая имеет лучшие возможности для таких вещей. Для вашего простого случая это будет хорошо.