Разработка ядра Linux - [193]

Шрифт
Интервал

>};

Обратите внимание на характерное имя структуры >list_head. Такое название выбрано, чтобы подчеркнуть, что списку не нужно головного элемента. Наоборот, обход списка можно начинать с любого элемента, и каждый элемент может быть головным. В связи с этим все элементы списка называются головными (list head). Указатель >next указывает на следующий элемент списка, а указатель >prev — на предыдущий элемент списка. Если текущий элемент списка является последним, то его указатель next указывает на первый узел. Если же текущим элементом является первый, то его указатель >prev указывает на последний узел списка. Благодаря элегантной реализации связанных списков без концепции головного элемента, можно вообще не вводить понятия первого и последнего элементов.

Структура >list_head сама по себе бесполезна. Ее необходимо включать в другие структуры данных.

>struct my_struct {

> struct list_head list;

> unsigned long dog;

> void *cat;

>};

Перед использованием элементы связанных списков должны быть инициализированы. Так как элементы связанных списков обычно создаются динамически (иначе, вероятно, не нужно использовать связанный список), то эти элементы, как правило, инициализируются во время выполнения.

>struct my_struct *p;

>/* выделить память для структуры my_struct ... */

>p->dog = 0;

>p->cat = NULL;

>INIT_LIST_HEAD(&p->list);

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

>struct my_struct mine = {

> .list = LIST_HEAD_INIT(mine.list),

> .dog = 0,

> .cat = NULL

>};

Для того чтобы создать и инициализировать связанный список, можно использовать следующее объявление.

>static LIST_HEAD(fox);

Эта команда позволяет статически создать связанный список с именем >fox.

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

Работа со связанными списками

Для работы со связанными списками ядро предоставляет семейство функций. Все они принимают указатели на одну или более структур >list_head. Все функции выполнены как функции с подстановкой тела (inline) на языке С, и их все можно найти в файле >.

Интересно, что время выполнения всех этих функций масштабируется как O(1)[97]. Это значит, что они выполняются в течение постоянного интервала времени независимо от количества элементов списка, для которого они вызываются. Например, время добавления элемента в связанный список из 3 и 3000 элементов будет одинаковым. Это, возможно, и не вызывает удивления, но тем не менее, приятно.

Для добавления элемента в связанный список можно использовать следующую функцию.

>list_add(struct list_head *new, struct list head *head);

Эта функция добавляет узел >new в заданный связанный список сразу после элемента >head. Поскольку связанный список является кольцевым и для него не существует понятий первого и последнего узлов, в качестве параметра >head можно использовать указатель на любой элемент списка. Если в качестве рассмотренного параметра всегда передавать указатель на последний элемент, то эту функцию можно использовать для организации стека.

Для добавления элемента в конец связанного списка служит следующая функция.

>list_add_tail(struct list_head *new,

> struct list_head *head);

Эта функция добавляет новый элемент new в связанный список сразу перед элементом, на который указывает параметр >head. Поскольку связанный список является кольцевым, то, как и в случае функции >list_add(), в качестве параметра >head можно передавать указатель на любой элемент списка. Эту функцию можно использовать для реализации очереди, если передавать указатель на первый элемент.

Для удаления узла списка служит следующая функция.

>list_del(struct list_head *entry);

Эта функция позволяет удалить из списка элемент, на который указывает параметр >entry. Обратите внимание, что эта функция не освобождает память, выделенную под структуру данных, содержащую узел списка, на который указывает параметр >entry. Данная функция просто удаляет узел из списка. После вызова этой функции обычно необходимо удалить структуру данных, в которой находится узел >list_head.

Для удаления узла из списка и повторной инициализации этого узла служит следующая функция.

>list_del_init(struct list head *entry);

Эта. функция аналогична функции >list_del(), за исключением того, что она дополнительно инициализирует указанную структуру >list_head из тех соображений, что эта структура данных больше не нужна в качестве элемента текущего списка и ее повторно можно использовать.

Для перемещения узла из одного списка в другой предназначена следующая функция.

>list_move(struct list_head *list, struct list_head *head);

Эта функция удаляет элемент >list из одного связанного списка и добавляет его в другой связанный список после элемента >head.

Для перемещения элемента из одного связанного списка в конец другого служит следующая функция.

>list_move_tail(struct list_head *list,


Рекомендуем почитать
Яйцо кукушки или Преследуя шпиона в компьютерном лабиринте

В отличие от плохого танцора, хорошему сисадмину мешают только кукушкины яйца. Их откладывают в его компьютер злобные хакеры, чтобы из них вылупились программы, делающие своего папу-кукушку суперпользователем. Но сколько кабелю не виться — а кончику быть: бравый сисадмин не дремлет и за годик-другой выводит злоумышленников на чистую воду: на этот раз хакерская тусовка круто пролетела. Такого предельно краткое содержание классической книги эксперта по компьютерной безопасности Клиффа Столла «Яйцо кукушки».


Создание отдела продаж с Битрикс24.CRM

Об отделах продаж написано очень много книг. Но, увы, информация в них быстро устаревает. Эта книга – о современном отделе продаж. Современный – значит, учитывающий основные возможности и требования к продавцам и руководителям продаж нашего времени. Интернет-маркетинг для привлечения новых покупателей, современные системы мотивации, скрипты продаж – и, конечно же, CRM. Представить себе современный отдел продаж без CRM уже просто нельзя. В этой книге, помимо методик продаж и полезных советов по работе с клиентами, дана практически пошаговая инструкция по работе с CRM.


Это ваше Fido

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


Безопасность информационных систем

В пособии излагаются основные тенденции развития организационного обеспечения безопасности информационных систем, а также подходы к анализу информационной инфраструктуры организационных систем и решению задач обеспечения безопасности компьютерных систем.Для студентов по направлению подготовки 230400 – Информационные системы и технологии (квалификация «бакалавр»).


Разработка приложений в среде Linux

Книга известных профессионалов в области разработки коммерческих приложений в Linux представляет собой отличный справочник для широкого круга программистов в Linux, а также тех разработчиков на языке С, которые перешли в среду Linux из других операционных систем. Подробно рассматриваются концепции, лежащие в основе процесса создания системных приложений, а также разнообразные доступные инструменты и библиотеки. Среди рассматриваемых в книге вопросов можно выделить анализ особенностей применения лицензий GNU, использование свободно распространяемых компиляторов и библиотек, системное программирование для Linux, а также написание и отладка собственных переносимых библиотек.


FAQ по смартфону Qtek 8300/8310

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