Вход/Регистрация
Разработка приложений в среде Linux. Второе издание
вернуться

Троан Эрик В.

Шрифт:

Если вам требуется доступ к глобальным данным из обработчика сигналов (что и делает большинство обработчиков), оставляйте структуры данных простыми. Хотя достаточно просто безопасно модифицировать отдельный элемент данных, такой как int, более сложные структуры обычно требуют блокировки сигналов. Любые глобальные переменные, которые могут быть модифицированы обработчиками сигналов, должны быть объявлены с ключевым словом

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

Другая вещь, с которой нужно соблюдать осторожность в обработчиках сигналов — это вызов других функций, потому что они тоже могут изменять глобальные данные! Библиотека С

stdio
пытается облегчить это и не допускает вызовов своих функций из обработчиков сигналов. В табл. 12.2 перечислены функции, которые гарантированно являются безопасными для вызова из обработчиков сигналов [66] ; вызовов всех прочих функций следует избегать.

Таблица 12.2. Реентерабельные функции

66

В табл. 12.2 перечислены функции, которые могут отсутствовать в некоторых, а может, даже во всех системах Linux. Мы включаем все функции, которые POSIX специфицирует в качестве безопасных для вызова из обработчиков сигналов.

abort
accept
access
aio_error
aio_return
aio_suspend
alarm
bind
cfgetispeed
cfgetospeed
cfsetispeed
cfsetospeed
chdir
chmod
chown
close
connect
creat
dup
dup2
execle
execve
_exit
fchmod
fchown
fcntl
fdatasync
fork
fpathconf
fstat
fsync
getegid
geteuid
getgid
getgroups
getpeername
getpgrp
getpid
getppid
getuid
kill
link
listen
lseek
lstat
mkdir
mkfifo
open
pathconf
pause
pipe
poll
posix_trace_event
pselect
raise
read
readlink
recv
recvfrom
recvmsg
rename
rmdir
select
sem_post
send
sendmsg
sendto
setgid
setpgid
setsid
setsockopt
setuid
shutdown
sigaction
sigaddset
sigdelset
sigemptyset
sigfillset
sigismember
signal
sigpause
sigpending
sigprocmask
sigqueue
sigset
sigsuspend
sleep
socket
socketpair
stat
symlink
sysconf
tcdrain
tcflow
tcflush
tcgetattr
tcgetpgrp
tcsendbreak
tcsetattr
tcsetpgrp
time
timer_getoverrun
timer_gettime
timer_settime
times
umask
uname
unlink
utime
wait
wait3
wait4
waitpid
write

12.5. Повторное открытие журнальных файлов

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

SIGHUP
и повторно открывать журнальные файлы. Это позволяет организовать ротацию журналов (периодическое открытие новых журнальных файлов при сохранении старых), используя простой сценарий вроде приведенного ниже.

dd /var/log

mv messages messages.old

killall -HUP syslogd

Logrotate (ftp://ftp.redhat.com/pub/redhat/code/logrotate/) — одна из программ, которая использует преимущество такого метода для выполнения безопасной ротации журналов.

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

Затем обработчик сигнала

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

 1: /*sighup.c*/

 2:

 3: #include <errno.h>

 4: #include <signal.h>

 5: #include <stdio.h>

 6: #include <string.h>

 7: #include <unistd.h>

 8:

 9: volatile int reopenLog = 0; /* volatile - поскольку модифицируется

10: обработчиком сигнала */

11:

12: /* записать строку в журнал */

13: void logstring(int logfd, char *str) {

14: write(logfd, str, strlen(str));

15: }

16:

17: /* когда приходит SIGHUP, сделать запись об этом и продолжить */

18: void hupHandler(int signum) {

19: reopenLog = 1;

20: }

21:

22: int main {

23: int done = 0;

24: struct sigaction sa;

25: int rc;

26: int logfd;

27:

28: logfd = STDOUT_FILENO;

29:

30: /* Установить обработчик сигнала SIGHUP. Использовать memset для

  • Читать дальше
  • 1
  • ...
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • ...

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

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: