C ++: продолжить выполнение после SIGINT - PullRequest
3 голосов
/ 09 января 2010

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

Я добавил signal(SIGINT, terminate); в начало основного и определенного завершения как:

void terminate(int param){
   cout << endl << endl << "Exit [N]ow, or [A]fter this url?" << endl;
   std::string answer;
   cin >> answer;
   if(answer[0] == 'n' || answer[0] == 'N'){
      terminateParser();
      exit(1);
   }else if(answer[0] == 'a' || answer[0] == 'A'){
      quitAfterUrl = true;
   }
}

В Linux это сработало так, как я ожидал, то есть ожидало ввода данных пользователем. Но когда я пытаюсь сделать то же самое в Windows, он показывает сообщение и в любом случае завершает работу.

Есть ли способ остановить немедленное закрытие программы SIGINT?

Обновление:

когда я пытался

BOOL WINAPI handler(DWORD dwCtrlType)
{
  if (CTRL_C_EVENT == dwCtrlType)
  {
    // ask the user
  }
  return FALSE;
}

, как предположил Грегори, программа все еще бесцеремонно закрывалась без остановки для пользовательского ввода.

Обновление 2: Я не совсем уверен, что это сделал, но код работает сейчас. Спасибо всем за помощь.

1 Ответ

8 голосов
/ 09 января 2010

От MSDN:

Примечание SIGINT не поддерживается ни для одного приложения Win32, включая Windows 98 / Me и Windows NT / 2000 / XP. Когда происходит прерывание CTRL + C, операционные системы Win32 генерируют новый поток для специальной обработки этого прерывания. Это может привести к тому, что однопоточное приложение, такое как UNIX, станет многопоточным, что приведет к неожиданному поведению.

Это означает, что вам придется использовать директиву предварительной обработки и реализовать специфичное для Windows решение .

BOOL WINAPI handler(DWORD dwCtrlType)
{
  if (CTRL_C_EVENT == dwCtrlType)
  {
    // ask the user
  }
  return FALSE;
}

А в начале main вы делаете

SetConsoleCtrlHandler(handler, TRUE);
...