1 executable queue
( based on real-time process scheduling )
The most basic data structure running queue in the scheduler (Runqueue) . The executable queue is a linked list of executable processes on a given processor, one per processor. Each operational process uniquely belongs to an executable queue. In addition, the executable queue also contains scheduling information for each processor. Therefore, the executable queue is also the most important data structure for each processor.
To avoid deadlocks, the code that locks multiple running queues must always obtain these locks in the same order : The order of the executable queue addresses from low to high.
Note: deadlock refers to two or more processes in the course of execution, because of competing resources or due to the communication between each other caused by a blocking phenomenon, if there is no external force, they will not be able to proceed. At this point the system is in a deadlock state or the system generates a deadlock, and these processes, which are always waiting on each other, are called deadlock processes.
Runqueue is a bidirectional loop queue, once the scheduling time is triggered, the kernel recalculates all the process running weights in the current queue and selects the highest-weighted process to run as the current process. Its drawbacks:
1 ) schedule trigger, recalculate runqueue run weights per process , the complexity is o (n)  
2 ) Runqueue managing both real-time and non-real-time processes (normal processes), the kernel calculates the operating weights through process attributes such as real-time or non-real-time, real-time process priorities, user processes, or kernel thread-related factors Count , low flexibility, and not easy to understand and maintain.
2 Priority series Group
Each run queue has two priority series groups, one active and one expired, which is Prio_array The structure of the type. A data structure that provides an O (1) level algorithm for the complexity of the order of precedence groups. Priority groups enable each priority of a runnable processor to contain a corresponding queue that contains the list of executable processes on the corresponding priority.
Each Priority group also contains a series called struct List_head queue, each linked list corresponds to a given priority, and each linked list contains all the running processes of the corresponding priority on the processor queue.
3 Recalculate time slices
& Nbsp; time slices in all processes ( cpu time assigned to each program )
the new Linux The Scheduler reduces the reliance on loops. Instead, it maintains two priority series groups for each processor : both active arrays and obsolete arrays. Processes on the executable queue in the active array also have time slices remaining, while processes on the executable queue in the expired array run out of time slices. When the time slice of a process is exhausted, it is moved to an expired array, but before that time slice has been recalculated.
4 Schedule ()
Select the next process and switch to it to execute is by Schedule () function is implemented. When the kernel code wants to hibernate, the function is called directly, and if any process is preempted, then the function is invoked. the schedule () function runs independently of each processor.
5 Calculating priority and time slices
& Nbsp; nice effective_prio () function can return the dynamic priority of a process. This function takes nice -5 Span style= "font-family: Song body; Background-color:inherit "> to +5 reward or penalty for process interactivity.
& Nbsp; some inferences to get an accurate reflection of how the process is i/o consumable or processor-consumable. The most obvious criterion is the length of time the process sleeps. If a process is dormant for most of its time, it is i/o consumption type. If a process executes longer than the time it sleeps, it is processor-intensive.
on the other hand, recalculating the time slice is relatively straightforward. It can be as long as it is based on a static priority. When a process is created, the new child process and the parent process divide the remaining process time slices of the parent process. Such allocations are fair and prevent users from constantly acquiring time slices by creating new processes. the task_timeslice () function returns a new time slice for a given task. The calculation of the time slice only needs to scale the priority proportionally, so that it conforms to the value range of the time slice.
The Scheduler also provides another mechanism to support interactive processes : If a process is highly interactive, it will be placed into an active array instead of an expired array when it is run out of time slices.
6 Sleep and wake up
Hibernate ( blocked ) process is in a special, non-executable state. The process marks itself as dormant, moves itself out of the executable queue, puts it into the waiting queue, and then calls Schedule () to Select and execute a different process. The process of awakening is the opposite : The process is set to executable state and then moved from the wait queue to the executable queue.
There are two related process states for hibernation: Task_interruptibleand thetask_uninterruptible. Hibernation is processed by waiting for a queue. The wait queue is a simple list of processes that wait for certain events to occur. Kernel withwake_queue_head_tto represent the wait queue. The wait queue can be passedDeclare_waitqueue ()created statically, or can beInit_waitqueue_head ()dynamically created. Wake-up operation via functionwake_up (), it wakes all the processes on the specified wait queue. There is a little need to note about sleep, there is a false wake. Sometimes the process wakes up not because the condition it waits for is reached, so a loop is needed to ensure that the condition it waits for is actually reached.
7 Load Balancing program
The load Balancing program hasKERNEL/SCHED.Cthe functions inload_balance ()to achieve. It has two methods of invocation. In theSchedule ()when executed, it is called as long as the current executable queue is empty. In addition, it is also called by the timer:every time the system is idle1milliseconds to call once or in other cases every $milliseconds to call once. The load balancer call requires that the executable queue of the current processor be locked and shielded from interruption to prevent the executable queue from being accessed concurrently.
Overview of "Linux" process scheduling