Ниже показано, как создать символическую ссылку и проверить ее с помощью программы
print-symlink
:
% ln -s /usr/bin/wc my_link
% ./print-symlink my_link
/usr/bin/wc
8.12. Функция sendfile: быстрая передача данных
Функция
sendfile
— это эффективный механизм копирования данных из одного файлового дескриптора в другой. Дескрипторам могут соответствовать дисковые файлы,
сокеты или устройства.
Обычно цикл копирования реализуется следующим образом. Программа выделяет буфер фиксированного размера, перемещает в него данные из исходного дескриптора, затем записывает содержимое буфера во второй дескриптор и повторяет описанную процедуру до тех пор, пока не будут скопированы все данные. Такая схема неэффективна как с точки зрения времени, так и с точки зрения затрат памяти, поскольку выделяется дополнительный буфер и над его содержимым выполняются операции копирования.
Функция
sendfile
устраняет потребность в создании промежуточного буфера. Ей передаются дескриптор для записи, дескриптор для чтения, указатель на переменную смещения и число копируемых данных. Переменная смещения определяет позицию входного файла, с которой начинается копирование (0 — это начало файла). После окончания копирования переменная будет содержать смещение конца блока. Функция
sendfile
объявлена в файле
<sys/sendfile.h>
.
Программа, показанная в листинге 8.10, представляет собой простую, но очень эффективную реализацию механизма файлового копирования. Она принимает в командной строке два имени файла и копирует содержимое первого файла во второй. Размер исходного файла определяется с помощью функции
fstat
.
Листинг 8.10. (сору.с) Копирование файла с помощью функции
часто используется для повышения эффективности копирования. Она широко применяется Web-серверами и сетевыми демонами, предоставляющими файлы
по сети клиентским программам. Запрос обычно поступает через сокет. Серверная программа открывает локальный дисковый файл, извлекает из него данные и записывает их в сокет. Благодаря функции
sendfile
эта операция существенно ускоряется.
8.13. Функция setitimer: задание интервальных таймеров
Функция
setitimer
является обобщением системного вызова
alarm
. Она планирует доставку сигнала по истечении заданного промежутка времени.
С помощью функции
setitimer
можно создавать таймеры трех типов.
■
ITIMER_REAL
. По истечении указанного времени процессу посылается сигнал
SIGALRM
.
■
ITIMER_VIRTUAL
. После того как процесс отработал требуемое время, ему посылается сигнал
SIGVTALRM
. Время, когда процесс не выполнялся (работало ядро или другой процесс), не учитывается.
■
ITIMER_PROF
. По истечении указанного времени процессу посылается сигнал
SIGPROF
. Учитывается время выполнения самого процесса, а также запускаемых в нем системных вызовов.
Код таймера задается в первом аргументе функции
setitimer
. Второй аргумент — это указатель на структуру типа
itimerval
, содержащую параметры таймера. Третий аргумент либо равен
NULL
, либо является указателем на другую структуру
itimerval
, куда будут записаны прежние параметры таймера.
В структуре
itimerval
два поля.
■
it_value
. Здесь находится структура типа
timeval
, где записано время отправки сигнала. Если это поле равно нулю, таймер отменяется.
■
it_interval
. Это еще одна структура
timeval
, определяющая, что произойдет после отправки первого сигнала. Если она равна нулю, таймер будет отменен. В противном случае здесь записан интервал генерирования сигналов.
Структура
timeval
была описана в разделе 8.7. "Функция
gettimeofday
: системные часы"
В листинге 8.11 показано, как с помощью функции
setitimer
отслеживать выполнение программы. Таймер настроен на интервал 250 мс, по истечении которого генерируется сигнал
SIGVTALRM
.
Листинг 8.11. (itimer.c) Пример создания таймера
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
void timer_handler(int signum) {
static int count = 0;
printf("timer expired %d times\n", ++count);
}
int main {
struct sigaction sa;
struct itimerval timer;
/* Назначение функции timer_handler обработчиком сигнала