LINUX.ORG.RU

работа с сигналами


0

0

поясните мне вот такую ситтуацию выполняется функция обрабатывается какойто объект , и в этот момент программа получает сигнал (HUP или ещё какой-нибудь). как я понимаю выполнение текущей операции обрывается и вызывается обработчик сигнала, а не получится ли так что какието данные изза этого могут потеряться ?

anonymous

вот например так

делаем sleep(50); и пока выполнение преостановленно посылаем -1 процессу , тутже вызывается обработчик , не дожидаясь завершения , а что будет если в эьтот момент будет происходить запись\чтение из файла или обрашение к базе данных ??

anonymous
()
Ответ на: комментарий от anonymous

> что будет если в эьтот момент будет происходить
> запись\чтение из файла

write() вернет число записанных байт или EINTR,
если у обработчика нет флага SA_RESTART.

некоторые вызовы, тот же sleep() всегда вернут
EINTR.

обработчик не вызывается "немедленно", он всегда
выполняется _после_ возврата из системного вызова.

idle ★★★★★
()

На самом деле с обработкой сигналов в Linux имеется некая морока.

Если процесс/нить висит в userspace, то сигнал будет доставлен сразу (межпроцессорным прерыванием).

Пока процесс/нить висит в ядре вообще ничего не происходит (просто во флагах нити помечается что ей есть сигнал), если код данной ядреной функции(и все что он вызывает) ничего не будет предпринимать, то сигнал будет действительно доставлен при возвращении в userspace.

Некоторые ядреные функции как и подобает классике временами проверяют pending флаг и могут предпринять некие активные действия при наличии ожидающего сигнала. В реальности это может быть все что угодно. Они могут захотеть перезапустить сигнал (тогда все зависит от настройки сигнал), они могут форсировать EINTR (и забить на все флажки).

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

Murr ★★
()
Ответ на: комментарий от Murr

> Если процесс/нить висит в userspace, то сигнал будет
> доставлен сразу (межпроцессорным прерыванием).

и опять-таки при возвращении в userspace из do_IRQ()

> Они могут захотеть перезапустить сигнал

s/сигнал/syscall/

> (тогда все зависит от настройки сигнал)

только при ERESTARTSYS. есть еще ERESTARTNOINTR



idle ★★★★★
()
Ответ на: комментарий от idle

>  > Если процесс/нить висит в userspace, то сигнал будет
>  > доставлен сразу (межпроцессорным прерыванием).
>
> и опять-таки при возвращении в userspace из do_IRQ()

собственно, я придрался для того, чтобы человек понял,
что сигнал выполняется самим процессом в обычном контексте.
а то многие считают, что обработчик исполняется ядром.
потому что даже в случае EINTR это _выглядит_ так, что
обработчик выполняется до возврата из вызова.

anonymous
()
Ответ на: комментарий от idle

>и опять-таки при возвращении в userspace из do_IRQ() безусловно... сигналы обрабатываются в userspace, поэтому туда нужно вернуться, чтобы его обработать. под словом "сразу" подразумевалась фиксированная задержка (которую можно посчитать в отличие от sys_read/sys_write, которые на ожидании страницы могут провести любое время) и по факту довольно небольшая.

>s/сигнал/syscall/ разумеется системные вызов. извиняюсь за описку. :)

>только при ERESTARTSYS. есть еще ERESTARTNOINTR да есть и такое но резюме остается прежним:

семантика обработки сигналов очень сильно завязана на конкретном коде ядра (а именно errno=-orig_eax=возвращаемому из sys-функции коду)

то есть в принципе: 1) обработка сигнала может быть отложена до упора 2) сигнал может быть обработан условным кодом ядра без перезапуска (EINTR) 3) сигнал может быть обработан с пожеланием перезапуска (ERESTART...) и фактическим перезапуском 4) сигнал может быть обработан с пожеланием перезапуска, но без соответствующих флажков в sigaction 5) все что угодно

это я и назвал кашей...

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

Murr ★★
()
Ответ на: комментарий от Murr

извиняюсь за форматирование... подзабыл, что по умолчанию такая голиматья с переносом строк. :)

Murr ★★
()
Ответ на: комментарий от Murr

мы, похоже, одновременно писали :)

я и не говорил, что вы в чем-то не правы, см
мой предыдущий пост, только он почему-то анонимным
получился :)

idle ★★★★★
()
Ответ на: комментарий от idle

Ага... одновременно. :)

Надеюсь, автор из моих сообщений что-нибудь разберет.
То, что из ваших разберет - это уж точно. :)

Блин, а вообще пора возвращаться к Linux... а то после полгода ничегонеделания мне даже в голову не пришло, что сигнал может придти во время прерывания. :)

Murr ★★
()
Ответ на: комментарий от Murr

> а именно errno=-orig_eax=возвращаемому из sys-функции коду

Ой! а вот здесь не правы. orig_eax - это то, с чем
мы _пришли_ в ядро. либо там номер вызова, либо там
-номер_прерывания. посмотрите на if (regs->orig_eax >= 0)
в handle_signal(). возврат всегда лежит в eax.

idle ★★★★★
()
Ответ на: комментарий от idle

ну да, просто eax. в orig_eax же сохраняется номер системного вызова для обратного вызова ptrace-сервера. :)

Murr ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.