Используя sigaction (), c

Я немного читал о sigaction() (источники взяты из моих заметок по курсу), и я не уверен, что понимаю этот текст:

Маска сигнала рассчитывается и устанавливается только на время работы обработчика сигнала.

По умолчанию сигнал «sig» также блокируется при появлении сигнала.

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

Означает ли это, что маска сигнала по умолчанию восстанавливается после возврата из обработчика сигнала? Кроме того, нужно ли мне переустанавливать обработчик после его использования, как если бы я использовал signal()?

Также есть этот фрагмент кода:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void termination_handler(int signum) {
    exit(7);
}

int main (void) {
  struct sigaction new_action,old_action;
  new_action.sa_handler = termination_handler;
  sigemptyset(&new_action.sa_mask);
  sigaddset(&new_action.sa_mask, SIGTERM);
  new_action.sa_flags = 0;
  sigaction(SIGINT, NULL, &old_action);
  if (old_action.sa_handler != SIG_IGN) {
         sigaction(SIGINT,&new_action,NULL);
  }
  sleep(10);
  return 0;
}

Итак - как именно будет обрабатываться SIGTERM? Я вижу, что установлен обработчик termination handler(), но затем SIGTERM был добавлен в маску сигнала без использования sigprocmask(). Что это значит? Спасибо!

P.s. последний вопрос: почему выражение if в main()?


person yotamoo    schedule 13.07.2012    source источник
comment
Вы когда-нибудь использовали собственный обработчик сигналов? Если нет, я советую сначала использовать собственный обработчик сигналов. Тогда sigaction будет легко понять. Выражение İf предназначено для сравнения (ожидаемый сигнал проверки пойман). И ответ на первый вопрос лежит на `продолжительности обработчика сигнала`.   -  person    schedule 13.07.2012


Ответы (1)


Попробуем разобраться, что происходит с модифицированной версией вашего кода:

#include <signal.h>
#include <stdio.h>

void termination_handler(int signum)
{
    printf("Hello from handler\n");
    sleep(1);
}

int main (void)
{
    //Structs that will describe the old action and the new action
    //associated to the SIGINT signal (Ctrl+c from keyboard).
    struct sigaction new_action, old_action;

    //Set the handler in the new_action struct
    new_action.sa_handler = termination_handler;
    //Set to empty the sa_mask. It means that no signal is blocked
    // while the handler run.
    sigemptyset(&new_action.sa_mask);
    //Block the SEGTERM signal.
    // It means that while the handler run, the SIGTERM signal is ignored
    sigaddset(&new_action.sa_mask, SIGTERM);
    //Remove any flag from sa_flag. See documentation for flags allowed
    new_action.sa_flags = 0;

    //Read the old signal associated to SIGINT (keyboard, see signal(7))
    sigaction(SIGINT, NULL, &old_action);

    //If the old handler wasn't SIG_IGN (it's a handler that just
    // "ignore" the signal)
    if (old_action.sa_handler != SIG_IGN)
    {
        //Replace the signal handler of SIGINT with the one described by new_action
        sigaction(SIGINT,&new_action,NULL);
    }

    while(1)
    {
        printf("In the loop\n");
        sleep(100);
    }
    return 0;
}

Итак, если вы скомпилируете его, запустите и нажмете Ctrl + C, то сообщение обработчика будет выполнено, а затем вы немедленно вернетесь из спящего режима основного сервера. Вы можете делать это сколько угодно раз, при этом сообщение обработчика и сообщение inloop по-прежнему отображаются.

Итак, вы даете функцию, а sigaction делает все необходимое, чтобы перехватить сигнал вашим обработчиком.


А что насчет sigterm? Если вы увеличите время сна в termination_handler, вы можете ввести что-то вроде "pkill --signal SIGTERM ./a.out" после нажатия Ctrl + C. Что происходит потом? Ничего такого! Сигнал SIGTERM блокируется во время работы termination_handler. Но как только вы вернетесь в основную систему, SIGTERM убьет приложение.

(Помните, что пока вы тестируете этот код, вы все равно можете убивать приложения, отправив сигнал SIGKILL.)


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

person Jeremy Cochoy    schedule 10.07.2013