Как обрабатывать сигнал Ctrl-Break в интерфейсе командной строки

голоса
5

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

Изменить: Я должен извиниться за мое объяснение до, по- видимому , я не сделал очень хорошую работу в объяснении его. Еще раз...

Я строй приложения интерфейса командной строки, который принимает команды от пользователя. У меня есть установка обработчика сигнала, чтобы поймать сигналы, которые затем устанавливает флаг, что мне нужно прекратить применение. Проблема у меня есть все функции консоли я могу найти блокирую, а это значит, что я не могу определить, что мне нужно, чтобы выйти из моего цикла обработки консоли, пока пользователь не нажмет клавишу (или ввести, в зависимости от функции ).

Есть ли какой-нибудь стандартный способ, я могу сделать что-либо взаимодействие консоли неблочного, или есть элегантный способ структурировать программу так, что если я просто завершаю из потока сигналов, что все будут обработаны и выпущены должным образом (пожалуйста, не СУЙ -Поймите это, я знаю, как это может быть сделано с помощью блокировки и освобождения ресурсов из сигнального потока, но это может запутаться, поэтому я предпочел бы избежать)

Надеюсь, что объяснение имеет смысл ...

Задан 08/10/2008 в 06:02
источник пользователем
На других языках...                            


5 ответов

голоса
8

OK - это работает для меня на Windows, и портативный - обратите внимание на #ifdef SIGBREAK - это не стандартный сигнал.

#include <csignal>
#include <iostream>
#include <ostream>
#include <string>
using namespace std;

namespace
{
    volatile sig_atomic_t quit;

    void signal_handler(int sig)
    {
        signal(sig, signal_handler);
        quit = 1;
    }
}

int main()
{
    signal(SIGINT, signal_handler);
    signal(SIGTERM, signal_handler);
#ifdef SIGBREAK
    signal(SIGBREAK, signal_handler);
#endif
    /* etc */

    while (!quit)
    {
        string s;
        cin >> s;
        cout << s << endl;
    }
    cout << "quit = " << quit << endl;
}
Ответил 08/10/2008 в 07:54
источник пользователем

голоса
6

На * Никс, вы можете использовать signalфункцию , чтобы зарегистрировать обработчик сигнала:


#include <signal.h>

void signal_handler(int sig)
{
  // Handle the signal
}

int main(void)
{
  // Register the signal handler for the SIGINT signal (Ctrl+C)
  signal(SIGINT, signal_handler);
  ...
}

Теперь, когда кто-то попадает Ctrl + C, ваш обработчик сигналов будет вызван.

Ответил 08/10/2008 в 06:07
источник пользователем

голоса
2

В Windows: SetConsoleCtrlHandler

Ответил 08/10/2008 в 06:05
источник пользователем

голоса
0

Лучше * Никс решение , которое является поточно является использование pthread_sigmask () вместо сигнала ().
Например, это, как вы синьор SIGINT, SIGTERM и SIGPIPE в текущем потоке и будущее породил темы:

sigset_t waitset;
sigemptyset(&waitset);
sigaddset(&waitset, SIGINT);
sigaddset(&waitset, SIGTERM);
sigaddset(&waitset, SIGPIPE);
pthread_sigmask(SIG_BLOCK, &waitset, NULL);  
Ответил 03/09/2013 в 14:31
источник пользователем

голоса
0

В системе, основанной на * NIX вы не могли бы действительно нужен обработчик сигнала для этой работы. Можно указать, что вы хотите игнорировать вызов SIGINT

int main(void)
{
  // Register to ignore the SIGINT signal (Ctrl+C)
  signal(SIGINT, SIG_IGN);

  while(1)
  {
    retval = my_blocking_io_func();
    if(retval == -1 && errno == EINTR)
    {
      // do whatever you want to do in case of interrupt
    }
  }
}

Важным способом, что это работает, чтобы признать, что неблокирующие функции не получают прерываться. Как правило, вы бы поняли, что функция блокировки не удалось (например, чтение ()) и повторить попытку функции. Если бы это было какое-то другое значение вы бы предпринять соответствующие действия, связанные ошибки.

Ответил 08/10/2008 в 06:28
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more