Linux: системный вызов имеет свой собственный обработчик сигнала?Могу ли я переопределить это? - PullRequest
0 голосов
/ 15 октября 2018

Документ по системному вызову read () говорит, что read() немедленно возвращается, если он прерывается сигналом.Возвращаемое значение отражает количество успешно прочитанных байтов.Кажется, подразумевается, что некоторые системные вызовы имеют свои собственные обработчики сигналов.

Если read() читает из канала (настроено pipe()), но в канале нет доступного байта, поэтому read() блокирует поток.Теперь, если я отправлю SIGINT с терминала (по Ctrl + C), программа завершит работу.

Предположим, в начале программы я установил обработчик сигнала для SIGINT, который печатает сообщение "SIGINT is received",Когда read() блокируется, и я использую Ctrl + C, программа завершит работу с напечатанным этим сообщением или программа все еще будет молча завершаться, потому что SIGINT уже обработан обработчиком сигнала read()?

(Мой эксперимент предполагает, что это последний случай ... не уверен)

1 Ответ

0 голосов
/ 18 октября 2018

Похоже, что некоторые системные вызовы имеют свои собственные обработчики сигналов.

Нет, абсолютно нет.Согласно read (2) справочная страница, когда чтение прерывается по сигналу, возвращается EINTR.Чтобы реализовать это поведение, вы должны обработать сигнал, т.е. установить для него обработчик.если вы отправите сигнал без обработки, тогда программа прекратит работу.

Теперь предположим, что вы обработали сигнал SIGINT и отправили его, когда программа заблокирована на read (2) , тогда можно наблюдать два поведения в зависимости ото том, как установить обработчик сигнала.

  1. , если сигнал обрабатывается с использованием sigaction (2) и SA_RESTART затем используется в соответствии с сигналом (7) man-страница, обработчик будет выполнен, и чтение будет автоматически перезапущено после возвращения обработчика сигнала.
  2. Если флаг SA_RESTART не используется, вызов завершается с ошибкой EINTR.

В обоих случаях программа не будет завершена, так как обрабатывается SIGINT.

Предположим, что при запуске программы я установил обработчик сигнала для SIGINT, который печатает сообщение "SIGINT получен».Когда read () блокирует и я использую Ctrl + C, программа завершит работу с напечатанным сообщением или программа все еще будет молча завершаться, потому что SIGINT уже обработан обработчиком сигнала read ()?

В обоих случаях программа не прекратит работу.Будет напечатано сообщение обработчика «SIGINT is receive», и программа продолжит свое выполнение.

...