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

на главную

Жанры

Разработка ядра Linux
Шрифт:

list_for_each(list, &father->children) {

 p = list_entry(list, struct task_struct, sibling);

 reparent_thread(p, reaper, child_reaper);

}

list_for_each(list, &father->ptrace_children) {

 p = list_entry(list, struct task_struct, ptrace_list);

 reparent_thread(p, reaper, child_reaper);

}

В этом программном коде организован цикл по двум спискам: по списку порожденных процессов child list и по списку порожденных процессов, находящихся в состоянии трассировки другими процессами ptraced child list. Основная причина, по которой используется именно два списка, достаточно интересна (эта новая особенность появилась в ядрах серии 2.6). Когда задача находится в состоянии ptrace,

для нее временно назначается родительским тот процесс, который осуществляет отладку (debugging). Когда завершается истинный родительский процесс для такого задания, то для такой дочерней задачи также нужно осуществить переназначение родительского процесса. В ядрах более ранних версий это приводило к необходимости организации цикла по всем заданиям системы для поиска порожденных процессов. Решение проблемы, как было указано выше, — это поддержка отдельного списка для порожденных процессов, которые находятся в состоянии трассировки, что уменьшает число операций поиска: происходит переход от поиска порожденных процессов по всему списку задач к поиску только по двум спискам с достаточно малым числом элементов.

Когда для процессов переназначение родительского процесса прошло успешно, больше нет риска, что какой-либо процесс навсегда останется в состоянии зомби. Процесс

init
периодически вызывает функцию
wait
для всех своих порожденных процессов и, соответственно, удаляет все зомби-процессы, назначенные ему.

Резюме

В этой главе рассмотрена важная абстракция операционной системы — процесс. Здесь описаны общие свойства процессов, их назначение, а также представлено сравнение процессов и потоков. Кроме того, описывается, как операционная система Linux хранит и представляет информацию, которая относится к процессам (структуры

task_struct
и
thread_info
), как создаются процессы (вызовы
clone
и
fork
), каким образом новые исполняемые образы загружаются в адресное пространство (семейство вызовов
exec
), иерархия процессов, каким образом родительский процесс собирает информацию о своих потомках (семейство функций
wait
) и как в конце концов процесс завершается (непроизвольно или с помощью вызова
exit
).

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

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

Глава 4

Планирование выполнения процессов

В предыдущей главе были рассмотрены процессы — абстракция операционной системы, связанная с активным программным кодом. В этой главе представлен планировщик процессов — код, который позволяет процессам выполняться.

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

Идея, лежащая в основе планирования выполнения процессов, достаточно проста. При наличии готовых к выполнению процессов, для того чтобы лучше использовать процессорное время, необходимо, чтобы всегда выполнялся какой-нибудь процесс. Если в системе процессов больше, чем процессоров, то некоторые процессы будут выполняться не во все моменты времени. Эти процессы готовы к выполнению (runnable). Исходя из информации о наборе готовых к выполнению процессов, выбор того процесса, который должен выполняться в следующий момент времени, и есть то фундаментальное решение, которое принимает планировщик.

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

приход данных по сети, наступление некоторого момента времени в будущем и т.д.). Следовательно, ОС Linux может содержать 100 процессов в памяти, но только один из них будет в исполняемом состоянии.

Многозадачные (multitasking) операционные системы бывают двух видов: системы с кооперативной (cooperative) многозадачностью и системы с вытесняющей (preemptive, преемптивной) многозадачностью. Операционная система Linux, так же как и большинство вариантов ОС Unix и других современных операционных систем, обеспечивает вытесняющую многозадачность. В системе с вытесняющей многозадачностью решение о том, когда один процесс должен прекратить выполнение, а другой возобновить его, принимает планировщик. Событие, заключающееся в принудительном замораживании выполняющегося процесса, называется вытеснением (preemption) этого процесса. Период времени, в течение которого процесс выполняется перед тем, как будет вытеснен, известен заранее. Этот период называется квантом времени (timeslice) процесса. В действительности квант времени соответствует той части процессорного времени, которая выделяется процессу. С помощью управления величинами квантов времени процессов планировщик принимает также и глобальное решение о планировании работы всей системы. При этом, кроме всего прочего, предотвращается возможность монопольного использования ресурсов всей системы одним процессом. Как будет показано далее, величины квантов времени в операционной системе Linux рассчитываются динамически, что позволяет получить некоторые интересные преимущества.

В противоположность рассмотренному выше типу многозадачности, в системах с кооперативной многозадачностью процесс продолжает выполняться до тех пор, пока он добровольно не примет решение о прекращении выполнения. Событие, связанное с произвольным замораживанием выполняющегося процесса, называется передачей управления (yielding). У такого подхода очень много недостатков: планировщик не может принимать глобальные решения относительно того, сколько процессы должны выполняться; процесс может монополизировать процессор на большее время, чем это необходимо пользователю; "зависший" процесс, который никогда не передает управление системе, потенциально может привести к неработоспособности системы. К счастью, большинство операционных систем, разработанных за последнее десятилетие, предоставляют режим вытесняющей многозадачности. Наиболее известным исключением является операционная система Mac OS версии 9 и более ранних версий. Конечно, операционная система Unix имеет вытесняющую многозадачность с момента своего создания.

При разработке ядер ОС Linux серии 2.5, планировщик ядра был полностью реконструирован. Новый тип планировщика часто называется O(1)-планировщиком (O(1) scheduler) в связи с соответствующим масштабированием времени выполнения алгоритма планирования [19] . Этот планировщик позволяет преодолеть недостатки предыдущих версий планировщика ядра Linux и обеспечить расширенную функциональность, а также более высокие характеристики производительности. В этой главе будут рассмотрены основы работы планировщиков, как эти основы использованы в О(1)-планировщике, а также цели создания O(1)-планировщика, его устройство, практическая реализация, алгоритмы работы и соответствующие системные вызовы.

19

Обозначение O(1) — это пример обозначения "большого O". Практически, эта запись означает, что планировщик может выполнить все свои действии за постоянное время, независимо от объема входных данных. Полное объяснение того, что такое обозначение "большого O", приведено в приложении В, "Сложность алгоритмов".

Стратегия планирования

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

Процессы, ограниченные скоростью ввода-вывода и скоростью процессора

Процессы можно классифицировать как те, которые ограничены скоростью ввода-вывода (I/O-bound), и те, которые ограничены скоростью процессора (processor-bound). К первому типу относятся процессы, которые большую часть своего времени выполнения тратят на отправку запросов на ввод-вывод информации и на ожидание ответов на эти запросы. Следовательно, такие процессы часто готовы к выполнению, но могут выполняться только в течение короткого периода времени, так как в конце концов они блокируются в ожидании выполнения ввода-вывода (имеются в виду не только дисковые операции ввода-вывода, но и любой другой тип ввода-вывода информации, как, например, работа с клавиатурой).

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

Санек 2

Седой Василий
2. Санек
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Санек 2

Князь Мещерский

Дроздов Анатолий Федорович
3. Зауряд-врач
Фантастика:
альтернативная история
8.35
рейтинг книги
Князь Мещерский

Без Чести

Щукин Иван
4. Жизни Архимага
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Без Чести

Безродный

Коган Мстислав Константинович
1. Игра не для слабых
Фантастика:
боевая фантастика
альтернативная история
6.67
рейтинг книги
Безродный

Огненный князь

Машуков Тимур
1. Багряный восход
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Огненный князь

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

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

Вторая невеста Драконьего Лорда. Дилогия

Огненная Любовь
Вторая невеста Драконьего Лорда
Любовные романы:
любовно-фантастические романы
5.60
рейтинг книги
Вторая невеста Драконьего Лорда. Дилогия

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

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

Девятое правило дворянина

Герда Александр
9. Истинный дворянин
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Девятое правило дворянина

Цеховик. Книга 1. Отрицание

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

Скрываясь в тени

Мазуров Дмитрий
2. Теневой путь
Фантастика:
боевая фантастика
7.84
рейтинг книги
Скрываясь в тени

Убивать чтобы жить 2

Бор Жорж
2. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 2

Идеальный мир для Лекаря 3

Сапфир Олег
3. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 3

Под маской, или Страшилка в академии магии

Цвик Катерина Александровна
Фантастика:
юмористическая фантастика
7.78
рейтинг книги
Под маской, или Страшилка в академии магии