First assignment: Process model analysis of Linux 2.6

1. What is a process?

According to my understanding, the process can be understood as the representation of the program . A program is a description of instructions, data, and their organization, while a process is the entity of the program. Process It is the basic unit of resource allocation and scheduling operation of the system, and the basic unit of the operating system operation target is the process.

 A process is an entity. Every process has its own address space. The text area stores code executed by the processor; the data area stores variables and dynamically allocated memory used during process execution; the stack area stores instructions and local variables for active procedure calls. Second, a process is a "program in execution". A program is an inanimate entity, and it can become an active entity only when the processor gives the program life (the operating system executes it), and we call it a process.

 

 

 

( For the processes in the WIN10 system, it can be seen that the system resources (such as CPU, memory, etc.) required by different processes are different)

 

The state of the process

 

进程状态的宏定义#define TASK_RUNNING        0  #define TASK_INTERRUPTIBLE    1  #define TASK_UNINTERRUPTIBLE    2  #define __TASK_STOPPED        4  #define __TASK_TRACED        8  /* in tsk->exit_state */  #define EXIT_ZOMBIE        16  #define EXIT_DEAD        32  /* in tsk->state again */  #define TASK_DEAD        64  #define TASK_WAKEKILL        128  #define TASK_WAKING        256  #define TASK_STATE_MAX        512 












 

 

 

This macro definition code lists the process states in the Linux system , which are:

 

1. TASK_RUNNING : Ready state, or running state. A process in this state is literally either already executing on the CPU or in a state ready to execute

 

2. TASK_INTERRUPTIBLE : Sleep state (or blocking state). In Linux, the sleep state is divided into a light sleep state and a deep sleep state, and this state is a light sleep state. According to my understanding, this state is similar to the introduction and understanding of the blocking state in the textbook. The operating system enters this state when it finds that the process cannot proceed further. When a specific external event occurs (such as passing a signal to wake up), the process can be transferred from this state to the ready state.

 

3. TASK_UNINTERRUPTIBLE : Sleep state. This state is a deep sleep state. Unlike the light sleep state, this state cannot be woken up by other processes through signals, nor can it be woken up by a clock interrupt.

 

4. EXIT_ZOMBIE : Zombie state. In Linux systems, processes that have been terminated but still retain some information and are waiting for the parent process to be recycled are called zombie processes (just like zombies in movies and games, although they are already dead, but the corpse is still walking around). The parent process can return information about the zombie child process through the wait() system.

 

5. EXIT_DEAD : After the parent process returns the information of the zombie child process through the wait() system, the process will be completely terminated.

 

6.    TASK_STOPPED : Pause state. The process enters the suspended state, and enters when the process receives the SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU signals.

 

7.    TASK_TRACED : Tracking status. When a process is being monitored by another process, any signal can put the process into tracking state.

 

Understanding of process state transitions :

At the very beginning, a process will be in the TASK_RUNNING state. The CPU allocates the time slice to the process, so that the process enters the running state of TASK_RUNNING; when the time slice is exhausted, the process will enter the ready state of TASK_RUNNING, waiting for the CPU to allocate the time slice (it is not running on the CPU at this time).

When the process is writing data to disk, waiting for resources to be in place, etc., the process will enter the TASK_(UN)INTERRUPTIBLE sleep state, and return to the ready state when resources are in place or data writing is complete.

Finally, when the process needs to exit, the process will be set to the EXIT_ZOMBIE zombie state. At this time, the memory occupied by the process is released and waits for the parent process to completely stop the process by calling the wait() class system. At this time, the process enters the EXIT_DEAD zombie cancellation state.

 

 

 Third, the scheduling method of the process

Understanding of process scheduling : The operating system uses the scheduler to schedule processes. The processor resources and time slice resources of the system are limited. When the resources required by all the processes currently running in the system are greater than the processor resources and time slice resources of the system, it is necessary to determine which processes need to be run preferentially. This work It needs to be handed over to the scheduler to complete. The scheduler decides how many system resources and time slices to allocate to the process according to parameters such as the priority of the process. In other words, the Linux system schedules processes based on time slices and priorities . For a process with a higher priority, the system allocates a longer time slice to the process.

 

 

Source code for process-to-priority definitions

#defineMAX_USER_RT_PRIO     100

#defineMAX_RT_PRIO      MAX_USER_RT_PRIO

#defineMAX_PRIO     (MAX_RT_PRIO+ 40)

#defineDEFAULT_PRIO     (MAX_RT_PRIO + 20)

 

 

 Linux processes are divided into ordinary processes and real-time processes , and real-time processes are divided into SCHED_FIFO and SCHED_RR . They only have static priorities, ranging from 0-99, while the priority of ordinary processes is from 100-139, so real-time processes are higher than ordinary processes. High priority.

 

 Linux source code for classification of processes

#define SCHED_NORMAL 0       // Ordinary process

#define SCHED_FIFO 1 //Real-time process, first in first out

#define SCHED_RR 2 //Real-time process, priority-based round robin

 

For tasks of the same priority, SCHED_RR is to assign each task a specific time slice, and then execute it in turn; while SCHED_FIFO is to allow a task to finish executing and then schedule the next task.

 

SCHED_NORMAL is a normal process, it not only has static priority, but also dynamic priority.

 

Static priority is defined when the process is defined. In layman's terms, static priority is the inherent priority of a process . It is converted with nice value. The nice value ranges from -20 to 19, which determines the priority and time slice, with 19 being the lowest and -20 the highest. Normal processes have static priorities ranging from 100 (highest priority) to 139 (lowest priority).

 

The calculation of dynamic priority is based on static priority, plus some variable values . The determinants of this variable value are the average sleep time of the process and the interactivity of the process. In short, the dynamic priority can be understood as the system generates a correction value to correct the static priority according to the actual running status of the process.

 

The function to calculate dynamic priority is

static int effective_prio(task_t *p)

{

       I nt bonus, prio; 

       if(rt_task(p))

              return p->prio;

       bonus= CURRENT_BONUS(p) - MAX_BONUS / 2;

       prio= p->static_prio - bonus;

       if(prio < MAX_RT_PRIO)

              prio= MAX_RT_PRIO;

       if(prio > MAX_PRIO-1)

              prio = MAX_PRIO-1;

       returnprio;

}

The bonus is the "change value" mentioned above, which will perform a round of operations with the static priority to generate the dynamic priority value.

 

The function to calculate the time slice is

 

#define SCALE_PRIO (x, prio) \

       max(x* (MAX_PRIO - prio) / (MAX_USER_PRIO/2), MIN_TIMESLICE)

static unsigned int task_timeslice(task_t*p)

{

       if(p->static_prio < NICE_TO_PRIO(0))

              returnSCALE_PRIO(DEF_TIMESLICE*4, p->static_prio);

       else

              returnSCALE_PRIO(DEF_TIMESLICE, p->static_prio);

}

 

The Linux system uses the runqueue data structure to represent a runnable queue, which is used to store the ready queue information of each CPU. The set of runnable state processes is implemented by an array of arrays in the runqueue. The array element type is prio_array_t .

 

 

struct prio_array {

         int nr_active;           //Number of processes   

         struct     list_head queue[MAXPRIO];   

         unsigned   long bitmap[BITMAP_SIZE];

}

 

 

When the time slice of an ordinary process is exhausted, its priority and time slice will be recalculated, it will be deleted from the active array (set of active processes) and added to the corresponding priority in expired array (set of expired processes). queue

 

 

4. My Views on the Operating System Process Model

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325169089&siteId=291194637