Механизмы замораживания и активизации.
Начнем с об"яснения механизма заморозки и его использования. Это включает в себя то, что процесс, будучи в замороженном состоянии (не функционирует), в какой - то момент времени можно активизировать, а затем опять заморозить (приостановить )!
Возможно, лучший способ понять механизм замораживания и активизации в Linux - изучение исходного текста функции __sleep_on(), использующейся для описания функций sleep_on() и interruptible_sleep_on().
static inline void __sleep_on(struct wait_queue **p, int state) { unsigned long flags; struct wait_queue wait = { current, NULL };
if (!p) return; if (current == task[0]) panic ( "task[0] trying to sleep"); current->state = state; add_wait_queue(p, &wait); save_flags(flags); sti(); schedule(); remove_wait_queue(p, &wait); restore_flags(flags); }
wait_queue - циклический список указателей на структуры задач, определенные в как
struct wait_queue { struct task_struct * task; struct wait_queue * next; };
Меткой состояния процесса в данном случае является или TASK_INTERRAPTIBLE, или TASK_UNINTERRAPTIBLE, в зависимости от того, может ли заморозка процесса прерываться такими вещами, как системные вызовы.Вообще говоря, механизм заморозки необходимо прерывать лишь в случае медленных устройств, так как такое устройство может приостановить на достаточно длительный срок работу всей системы. add_wait_queue() отключает прерывание, создает новый элемент структуры wait_queue, определенной в начале функции как список p.Затем она восстанавливает в исходное положение метку о состоянии процесса.
save_flags() - макрос, сохраняющий флаги процессов, задаваемых в виде аргументов. Это делается для фиксации предыдущего положения метки состояния процесса. Таким образом, функция restore_flags() может восстанавливать положение метки.
Функция sti() затем разрешает прерывания, а schedule() выбирает для выполнения следующий процесс. Задача не может быть избранной для выполнения, пока метка не будет находиться в состоянии TASK_RUNNING.
Это достигается с помощью функции wake_up(),примененной к задаче, ждущей в структуре p своей очереди.
Затем процесс исключает себя из wait_queue,восстанавливает состояние положения прерывания с помощью restore_flags() и завершает работу.
Для определения очередности запросов на ресурсы в структуру wait_queue введены указатели на задачи, использующие этот ресурс. В таком случае, когда несколько задач запрашивают один и тот же ресурс одновременно, задачи, не получившие доступ к ресурсу, замораживаются в wait_queue.По окончании работы текущей задачи активизируется следующая задача из wait_queue,относящаяся к этому ресурсу с помощью функций wake_up() или wake_up_interruptible().
Если вы хотите понять последовательность разморозки задач или более детально изучить механизм заморозки, вам нужно купить одну из книг, предложенных в приложении А и просмотреть !mutual exclusion! и !deadlock!.