Scroll to navigation

SIGNAL-SAFETY(7) Руководство программиста Linux SIGNAL-SAFETY(7)

ИМЯ

signal-safety - функции async-signal-safe

ОПИСАНИЕ

Функцией async-signal-safe называется функция, которую безопасно вызывать внутри обработчика сигналов. Многие функции не являются async-signal-safe. В частности, нереентерабельные функции, обычно, небезопасно вызывать в обработчиках сигналов.

Виды проблем, которые делают функцию небезопасной, можно быстро понять на примере реализации библиотеки stdio, все функции которой являются не async-signal-safe.

При выполнении буферизируемого ввода-вывода в файл функции stdio должны вести статически выделенный буфер и связанные с ним счётчики и индексы (или указатели), содержащие количество данных и текущее положение в буфере. Предположим, что основная программа находится в середине вызова функции stdio, например printf(3), которая обновляет часть буфера и связанных переменных. Если в этот момент программа прервётся обработчиком сигнала, который также вызывает printf(3), то второй вызов printf(3) будет работать с не целостными данными и результат будет непредсказуем.

Чтобы не возникало проблем с небезопасными функциями есть два варианта:

1.
Следить, чтобы (а) обработчик сигнала вызывал только функции async-signal-safe, и (б) сам обработчик сигнала был реентерабельным по отношению к глобальным переменным основной программы.
2.
Блокировать доставку сигнала в основной программе при вызове небезопасных функций или при работе с глобальными данными, доступными из обработчика сигнала.

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

В POSIX.1 определён набор функций, реализация которых должна быть async-signal-safe (реализация может предоставлять безопасную реализацию и других функций, но это не требуется стандартом и другие реализации могут не предоставлять те же гарантии) Обычно, функция является async-signal-safe или потому что она реентерабельная, или из-за её атомарности по отношению к сигналам (т. е., её выполнение не может быть прервано обработчиком сигнала).

Набор функций async-signal-safe по POSIX.1 показан в таблице далее. Функции, если не указано обратное, являются async-signal-safe и по POSIX.1-2001; в таблице отмечены изменения в последующих стандартах.

функция Примечания
abort(3) Добавлена в POSIX.1-2003
accept(2)
access(2)
aio_error(3)
aio_return(3)
aio_suspend(3) смотрите замечания далее
alarm(2)
bind(2)
cfgetispeed(3)
cfgetospeed(3)
cfsetispeed(3)
cfsetospeed(3)
chdir(2)
chmod(2)
chown(2)
clock_gettime(2)
close(2)
connect(2)
creat(2)
dup(2)
dup2(2)
execl(3) Добавлена в POSIX.1-2008; смотрите замечания ниже
execle(3) смотрите замечания далее
execv(3) Добавлена в POSIX.1-2008
execve(2)
_exit(2)
_Exit(2)
faccessat(2) Добавлена в POSIX.1-2008
fchdir(2) Добавлена в POSIX.1-2013
fchmod(2)
fchmodat(2) Добавлена в POSIX.1-2008
fchown(2)
fchownat(2) Добавлена в POSIX.1-2008
fcntl(2)
fdatasync(2)
fexecve(3) Добавлена в POSIX.1-2008
ffs(3) Добавлена в POSIX.1-2016
fork(2) смотрите замечания далее
fstat(2)
fstatat(2) Добавлена в POSIX.1-2008
fsync(2)
ftruncate(2)
futimens(3) Добавлена в POSIX.1-2008
getegid(2)
geteuid(2)
getgid(2)
getgroups(2)
getpeername(2)
getpgrp(2)
getpid(2)
getppid(2)
getsockname(2)
getsockopt(2)
getuid(2)
htonl(3) Добавлена в POSIX.1-2016
htons(3) Добавлена в POSIX.1-2016
kill(2)
link(2)
linkat(2) Добавлена в POSIX.1-2008
listen(2)
longjmp(3) Добавлена в POSIX.1-2016; смотрите замечания ниже
lseek(2)
lstat(2)
memccpy(3) Добавлена в POSIX.1-2016
memchr(3) Добавлена в POSIX.1-2016
memcmp(3) Добавлена в POSIX.1-2016
memcpy(3) Добавлена в POSIX.1-2016
memmove(3) Добавлена в POSIX.1-2016
memset(3) Добавлена в POSIX.1-2016
mkdir(2)
mkdirat(2) Добавлена в POSIX.1-2008
mkfifo(3)
mkfifoat(3) Добавлена в POSIX.1-2008
mknod(2) Добавлена в POSIX.1-2008
mknodat(2) Добавлена в POSIX.1-2008
ntohl(3) Добавлена в POSIX.1-2016
ntohs(3) Добавлена в POSIX.1-2016
open(2)
openat(2) Добавлена в POSIX.1-2008
pause(2)
pipe(2)
poll(2)
posix_trace_event(3)
pselect(2)
pthread_kill(3) Добавлена в POSIX.1-2013
pthread_self(3) Добавлена в POSIX.1-2013
pthread_sigmask(3) Добавлена в POSIX.1-2013
raise(3)
read(2)
readlink(2)
readlinkat(2) Добавлена в POSIX.1-2008
recv(2)
recvfrom(2)
recvmsg(2)
rename(2)
renameat(2) Добавлена в POSIX.1-2008
rmdir(2)
select(2)
sem_post(3)
send(2)
sendmsg(2)
sendto(2)
setgid(2)
setpgid(2)
setsid(2)
setsockopt(2)
setuid(2)
shutdown(2)
sigaction(2)
sigaddset(3)
sigdelset(3)
sigemptyset(3)
sigfillset(3)
sigismember(3)
siglongjmp(3) Добавлена в POSIX.1-2016; смотрите замечания ниже
signal(2)
sigpause(3)
sigpending(2)
sigprocmask(2)
sigqueue(2)
sigset(3)
sigsuspend(2)
sleep(3)
sockatmark(3) Добавлена в POSIX.1-2004
socket(2)
socketpair(2)
stat(2)
stpcpy(3) Добавлена в POSIX.1-2016
stpncpy(3) Добавлена в POSIX.1-2016
strcat(3) Добавлена в POSIX.1-2016
strchr(3) Добавлена в POSIX.1-2016
strcmp(3) Добавлена в POSIX.1-2016
strcpy(3) Добавлена в POSIX.1-2016
strcspn(3) Добавлена в POSIX.1-2016
strlen(3) Добавлена в POSIX.1-2016
strncat(3) Добавлена в POSIX.1-2016
strncmp(3) Добавлена в POSIX.1-2016
strncpy(3) Добавлена в POSIX.1-2016
strnlen(3) Добавлена в POSIX.1-2016
strpbrk(3) Добавлена в POSIX.1-2016
strrchr(3) Добавлена в POSIX.1-2016
strspn(3) Добавлена в POSIX.1-2016
strstr(3) Добавлена в POSIX.1-2016
strtok_r(3) Добавлена в POSIX.1-2016
symlink(2)
symlinkat(2) Добавлена в POSIX.1-2008
tcdrain(3)
tcflow(3)
tcflush(3)
tcgetattr(3)
tcgetpgrp(3)
tcsendbreak(3)
tcsetattr(3)
tcsetpgrp(3)
time(2)
timer_getoverrun(2)
timer_gettime(2)
timer_settime(2)
times(2)
umask(2)
uname(2)
unlink(2)
unlinkat(2) Добавлена в POSIX.1-2008
utime(2)
utimensat(2) Добавлена в POSIX.1-2008
utimes(2) Добавлена в POSIX.1-2008
wait(2)
waitpid(2)
wcpcpy(3) Добавлена в POSIX.1-2016
wcpncpy(3) Добавлена в POSIX.1-2016
wcscat(3) Добавлена в POSIX.1-2016
wcschr(3) Добавлена в POSIX.1-2016
wcscmp(3) Добавлена в POSIX.1-2016
wcscpy(3) Добавлена в POSIX.1-2016
wcscspn(3) Добавлена в POSIX.1-2016
wcslen(3) Добавлена в POSIX.1-2016
wcsncat(3) Добавлена в POSIX.1-2016
wcsncmp(3) Добавлена в POSIX.1-2016
wcsncpy(3) Добавлена в POSIX.1-2016
wcsnlen(3) Добавлена в POSIX.1-2016
wcspbrk(3) Добавлена в POSIX.1-2016
wcsrchr(3) Добавлена в POSIX.1-2016
wcsspn(3) Добавлена в POSIX.1-2016
wcsstr(3) Добавлена в POSIX.1-2016
wcstok(3) Добавлена в POSIX.1-2016
wmemchr(3) Добавлена в POSIX.1-2016
wmemcmp(3) Добавлена в POSIX.1-2016
wmemcpy(3) Добавлена в POSIX.1-2016
wmemmove(3) Добавлена в POSIX.1-2016
wmemset(3) Добавлена в POSIX.1-2016
write(2)

Замечания:

  • В POSIX.1-2001 и POSIX.1-2004 требуется, чтобы функции fpathconf(3), pathconf(3) и sysconf(3) были async-signal-safe, но это требование удалено в POSIX.1-2008.
  • Если обработчик сигнала прерывает выполнение небезопасной функции и обработчик завершается вызовом longjmp(3) или siglongjmp(3) и далее программа вызывает небезопасную функцию, то поведение программы непредсказуемо.
  • В POSIX.1-2003 уточнено, что если приложение вызывает fork(2) из обработчика сигнала и и зарегистрированный обработчик fork (с помощью pthread_atfork(3)) вызывает не async-signal-safe функцию, то поведение непредсказуемо. Вероятно, в будущих версиях стандарта вызов fork(2) будет удалён из списка функций async-signal-safe.

Отклонения в библиотеке GNU C

В библиотеке GNU C есть следующие известные отклонения от стандарта:

  • До glibc 2.24 внутри execl(3) и execle(3) использовалась realloc(3) и поэтому они были не безопасны для асинхронных сигналов. Это было исправлено в glibc 2.24.
  • Реализация aio_suspend(3) в glibc не является безопасной для асинхронных сигналов, так как в ней используется pthread_mutex_lock(3).

СМ. ТАКЖЕ

sigaction(2), signal(7), standards(7)

ЗАМЕЧАНИЯ

Эта страница является частью проекта Linux man-pages версии 4.16. Описание проекта, информацию об ошибках и последнюю версию этой страницы можно найти по адресу https://www.kernel.org/doc/man-pages/.

ПЕРЕВОД

Русский перевод этой страницы руководства был сделан Alexander Golubev <fatzer2@gmail.com>, Azamat Hackimov <azamat.hackimov@gmail.com>, Hotellook, Nikita <zxcvbnm3230@mail.ru>, Spiros Georgaras <sng@hellug.gr>, Vladislav <ivladislavefimov@gmail.com>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>

Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на man-pages-ru-talks@lists.sourceforge.net.

13 марта 2017 г. Linux