Системные вызовы setitimerO и alarm
Linux позволяет процессам режима пользователя активизировать специальные таймеры, называемые таймерами интервалов. Эти таймеры периодически отправляют процессу сигналы. Кроме того, есть возможность активизировать таймер интервалов так, чтобы он отправил только один сигнал по истечении заданного времени.
Таким образом, каждый таймер интервалов характеризуется:
- частотой отправки сигналов или нулевым значением, если генерируется только один сигнал;
- временем, остающимся до отправки следующего сигнала.
Предупреждение о точности таймеров, сделанное нами ранее, справедливо и в отношении таймеров интервалов. Они гарантированно выполняются по прошествии заданного отрезка времени, но точный момент срабатывания предсказать невозможно.
Таймеры интервалов активизируются системным вызовом setitimerO, определенным в стандарте POSIX.
Его первый параметр определяет политику, проводимую таймером:
- itimer real— фактический отрезок времени; процесс получает сигналы
SIGALRM.
- itimer virtual— время, проведенное процессом в режиме пользователя; процесс получает сигналы sigvtalrm;
- itimer prof— время, проведенное процессом как в режиме пользователя, так и в режиме ядра; процесс получает сигналы sigprof.
Таймеры интервалов бывают либо однократно срабатывающими, либо периодическими. Второй параметр системного вызова setitimer - указывает на структуру типа itimerval, задающую продолжительность первоначального интервала таймера (в секундах или наносекундах) и продолжительность интервала при автоматической повторной активизации таймера (либо ноль, если таймер однократный). Третий параметр системного вызова setitimerO является необязательным указателем на некую структуру типа itimerval, которую системный вызов заполняет предыдущими параметрами таймера.
Чтобы реализовать таймер интервалов для каждой из политик, описанных ранее, дескриптор процесса включает в себя три пары полей:
- it_real_incr И it_real_value;
- it_virt_incr И it_virt_value;
- it_prof_incr И it_prof_value.
Первое поле в каждой паре хранит интервал между двумя сигналами, измеренный в тиках; второе содержит текущее значение таймера.
Таймер интервалов itimer real реализуется с помощью динамических таймеров, потому что ядро должно посылать сигналы процессу, даже когда он не выполняется на процессоре. Поэтому каждый дескриптор процесса включает в себя объект "динамический таймер", называемый reai timer. Системный вызов setitimer инициализирует поля объекта reai timer, а затем вызывает функцию add timer , чтобы занести динамический таймер в соответствующий список. Когда время таймера истечет, ядро выполнит таймерную функцию it reai fn . Функция it_reai_fn отправляет процессу сигнал sigalrm, после чего, если значение it reai incr не равно нулю, устанавливает поле expires, заново активизируя таймер.
Реализация таймеров itimer virtual и itimer prof не требует динамических таймеров, поскольку эти таймеры интервалов могут быть обновлены по ходу выполнения процесса. Соответствующие функции account it virt о и account it prof вызываются функцией update_process_times , которая вызывается либо обработчиком прерываний, возбуждаемых программируемым таймером интервалов (в однопроцессорной системе), либо обработчиками локальных таймерных прерываний (в многопроцессорной системе). В результате эти два интервальных таймера обновляются на каждом тике, а когда их время истечет, то текущему процессу будет отправлен соответствующий сигнал.
Системный вызов alarm о посылает вызвавшему процессу сигнал sigalrm по истечении заданного отрезка времени. Он очень похож на системный вызов setitimer , сделанный с параметром itimer real, потому что тоже пользуется динамическим таймером reai timer, включенным в состав дескриптора процесса. Поэтому вызов alarm о и вызов setitimer о с параметром itimer real не могут быть одновременными.
Предыдущая страница | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | Следующая страница