Чтение онлайн

на главную - закладки

Жанры

Linux программирование в примерах
Шрифт:

Carter James 39 222631200

Данные сортируются на основе сначала фамилии, затем имени, а затем старшинства. При запуске [160] программа выдает следующий результат:

$ ch14-tsearch < presdata.txt

Depth: 1. Employee:

Bush, George 41 Fri Jan 20 13:00:00 1989

Depth: 0. Employee:

Bush, George 43 Sat Jan 20 13:00:00 2001

160

Этот вывод для часового пояса U.S. Eastern Time zone — Примеч. автора.

Depth: 2. Employee:

Carter, James 39 Thu Jan 20 13:00:00 1977

Depth: 1. Employee:

Clinton, William 42 Wed Jan 20 13:00:00 1993

Depth: 2. Employee:

Reagan, Ronald 40 Tue Jan 20 13:00:00 1981

14.4.6. Удаление вершины дерева и удаление дерева:

tdelete
и
tdestroy

Наконец, вы можете удалить элементы из дерева и, на системах GLIBC, удалить само дерево целиком:

void *tdelete(const void *key, void **rootp,

int (*compare)(const void*, const void*));

/* Расширение GLIBC, в POSIX нет: */

void tdestroy(void *root, void (*free_node)(void *nodep));

Аргументы для

tdelete
те же, что и для
tsearch
: ключ, адрес корня дерева и функция сравнения. Если в дереве найден данный элемент, он удаляется, и
tdelete
возвращает указатель на родительскую вершину. В противном случае возвращается
NULL
. С этим поведением следует обращаться в своем коде осмотрительно, если вам нужен первоначальный удаляемый элемент, например, для освобождения занимаемой им памяти.

struct employee *е, key; /* Объявления переменных */

void *vp, *root;

/* ...заполнить ключ для удаляемого из дерева элемента... */

vp = tfind(&key, root, emp_name_id_compare); /* Найти удаляемый элемент */

if (vp != NULL) {

 e = *((struct employee**)vp); /* Преобразовать указатель */

 free(e); /* Освободить память */

}

(void)tdelete(&key, &root, emp_name_id_compare); /* Теперь удалить его из дерева */

Хотя это и не указано в справочных страницах или стандарте POSIX, под GNU/Linux, если вы удаляете элемент, хранящийся в корневой вершине, возвращается значение новой корневой вершины. Для переносимого кода не следует полагаться на это поведение

Функция

tdestroy
является расширением GLIBC. Она позволяет удалить дерево целиком. Первый аргумент является корнем дерева. Второй является указателем на функцию, которая освобождает данные, на которые указывает каждая вершина дерева. Если с этими данными ничего не надо делать (например, они хранятся в обычном массиве, как в примере нашей программы), эта функция ничего не должна делать. Не передавайте указатель
NULL
! Это приведет к аварийной ситуации.

14.5. Резюме

• Иногда бывает необходимо выделить память, выровненную по определенной границе. Это осуществляет

posix_memalign
. Ее возвращаемое значение отличается от большинства из рассмотренных в данной книге функций.
memalign
также выделяет выровненную память, но не все системы поддерживают освобождение памяти с помощью
free
.

• Блокирование файлов с помощью

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

• GNU/Linux функция

lockf
действует в качестве оболочки вокруг блокировки POSIX с помощью
fcntl
; блокировки функции BSD
flock
совершенно независимы от блокировок
fcntl
. Блокировки BSD
flock
используются лишь для всего файла в целом и не работают на удаленных файловых системах. По этим причинам использование блокировки
flock
не рекомендуется.

• 

gettimeofday
получает время дня в виде пар (секунды, микросекунды) в
struct timeval
. Эти значения используются
utimes
для обновления времени доступа и модификации файла. Системные вызовы
gettimer
и
settimer
используют пары
struct timeva
l в
struct itimerval
для создания интервальных таймеров — сигнальных часов, которые «срабатывают» в установленное время и продолжают срабатывать впоследствии с заданным интервалом. Три различных таймера обеспечивают контроль тех состояний, когда таймер продолжает действовать.

• Функция

nanosleep
использует
struct timespec
, которая указывает время в секундах и наносекундах, чтобы приостановить выполнение процесса в течение определенного интервала времени. У нее есть удачная особенность не взаимодействовать вообще с механизмами сигналов.

• Три API являются стандартным набором функций для хранения и поиска данных, которые сохраняют данные в двоичных деревьях в отсортированном виде. Эти три API очень гибкие, позволяя использовать множество деревьев и произвольные данные.

Упражнения

1. Напишите функцию

lockf
, используя
fcntl
для осуществления блокировки.

2. Каталог

/usr/src/linux/Documentation
содержит набор файлов, которые описывают различные аспекты поведения операционной системы. Прочитайте файлы
locks.txt
и
mandatory.txt
, чтобы получить больше сведений об обработке Linux блокировок файлов.

3. Запустите на своей системе программу

ch14-lockall
без обязательной блокировки и посмотрите, сможете ли изменить файл-операнд.

4. Если у вас не-Linux система, поддерживающая обязательную блокировку, попробуйте исполнить на ней программу

ch14-lockall
.

5. Напишите функцию

strftimes
следующего вида:

size_t strftimes(char *buf, size_t size, const char *format,

 const struct timeval *tp);

Она должна вести себя подобно стандартной функции

strftime
за тем исключением, что должна использовать
%q
для обозначения «текущего числа микросекунд».

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

Очерки времен и событий из истории российских евреев. 1945 – 1970 гг. Книга 6

Кандель Феликс Соломонович
Научно-образовательная:
история
5.00
рейтинг книги
Очерки времен и событий из истории российских евреев. 1945 – 1970 гг. Книга 6

Вечный. Книга IV

Рокотов Алексей
4. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга IV

Эволюционер из трущоб. Том 11

Панарин Антон
11. Эволюционер из трущоб
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Эволюционер из трущоб. Том 11

Кодекс Императора III

Сапфир Олег
3. Кодекс Императора
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Кодекс Императора III

Мастер 4

Чащин Валерий
4. Мастер
Фантастика:
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Мастер 4

Гамбургский счет: Статьи – воспоминания – эссе (1914–1933)

Шкловский Виктор Борисович
Научно-образовательная:
история
5.00
рейтинг книги
Гамбургский счет: Статьи – воспоминания – эссе (1914–1933)

Цеховик. Книга 2. Движение к цели

Ромов Дмитрий
2. Цеховик
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Цеховик. Книга 2. Движение к цели

Дважды одаренный. Том VI

Тарс Элиан
6. Дважды одаренный
Фантастика:
аниме
альтернативная история
фэнтези
фантастика: прочее
5.00
рейтинг книги
Дважды одаренный. Том VI

Ваше Сиятельство 4т

Моури Эрли
4. Ваше Сиятельство
Любовные романы:
эро литература
5.00
рейтинг книги
Ваше Сиятельство 4т

Изгой Проклятого Клана. Том 6

Пламенев Владимир
6. Изгой
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Изгой Проклятого Клана. Том 6

Черный Маг Императора 23

Герда Александр
23. Черный маг императора
Фантастика:
юмористическое фэнтези
аниме
сказочная фантастика
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Черный Маг Императора 23

Звездная Кровь. Экзарх VII

Рокотов Алексей
7. Экзарх
Фантастика:
боевая фантастика
рпг
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Звездная Кровь. Экзарх VII

Последний реанорец. Том I и Том II

Павлов Вел
1. Высшая Речь
Фантастика:
фэнтези
7.62
рейтинг книги
Последний реанорец. Том I и Том II

Кодекс Крови. Книга ХIV

Борзых М.
14. РОС: Кодекс Крови
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга ХIV