Process
The process represents a running instance of a program, which is the smallest unit of allocation of resources, which is particularly official.
Process is a very important thing, we run a system running n processes at the same time, these processes are silently working, we write code, compiled, run, will also generate a process. This process consists of program code, data, variables (which occupy the system memory), open files (file descriptors), and the environment. In general, for Linux systems, program code and system function libraries are shared between processes, so at any point in memory there is only one copy of the code.
Because the process is so important, this article makes a basic summary of the process in Linux.
Create a process
The story starts with creating a process first. Take a look at the following code:
#include <stdio.h> #include <unistd.h> #include <stdlib.h>int main () { pid_t pid; char *msg; int n; printf ("Fork program starting\n"); PID = fork (); After creating a process //creation, both the parent and child processes start from here to run switch (PID) { case-1: perror ("Fork failed."); Exit (exit_failure); Case 0: //When Fork returns a value of 0 o'clock, indicating that it is a subprocess msg = "This is the child "; n = 2; break; Default: //When fork is not 0 and-1, indicates that it is the parent process msg = "This is the parent"; n = 3; break; } for (; n > 0;--n) { printf ("%s\n", msg); Sleep (1); } Exit (exit_success);}
We use the fork function to create a child process, and the fork function declares the following:
#include <unistd.h>pid_t fork (void);
The fork function returns a value of type pid_t, and the pid_t type is an int type. When the call fork creation process succeeds, both the child process and the parent process run from the code after the fork function. So how do you differentiate between a child process or a parent process since it is all running from the same place?
The return value of fork is used in Linux to differentiate by using the following method:
- When fork returns the value of pid_t-1, it indicates that the creation process has encountered an error;
- When fork returns the value of pid_t to 0 o'clock, it is a child process;
- When fork returns a value of pid_t that is not 0 and 1, the parent process is represented.
In the above code, I'm judging whether a child or parent process is based on the return value of the fork. It's a weird feeling.
Structure of the process
Again, the process is important and we need to understand that the structure of the process has to be said. So what is the structure of the process in memory after we have created a process using fork? Let's take a look.
As shown in the actual coding, we do not take into account what is said in the diagram, but what is shown is the key to understanding the parent process and the child process, many questions about the process, we also based on the starting to think. In the following, I will specifically come up with a few questions to analyze why the process memory image is so important.
Process scheduling
On a single processor, only one process can run at a time and the other processes are waiting to run. However, what we actually feel is that there are multiple processes at the same time running at "simultaneous", which is why?
The operating system will give each process a certain run time, called "Time slice". The process runs in this "time slice" because the "time slice" is so short that it gives the illusion that multiple programs are running simultaneously. How does the operating system dispatch the process? There are many rules for process scheduling, such as scheduling algorithm based on priority, FIFO scheduling algorithm and so on.
The Linux kernel Process Scheduler is a process scheduler based on the priority of the process. High-priority processes run more frequently.
Process status
There are 5 states of processes on Linux:
- Running (running or waiting in the running queue)
- Interrupt (dormant, blocked, waiting for a condition to form or receive a signal)
- Non-interruptible (Received signal does not wake up and cannot be run, process must wait until interrupt occurs)
- Zombie (The process has been terminated, but the process descriptor exists until the parent process calls WAIT4 () after the system call is released)
- Stop (process receives sigstop, SIGSTP, Sigtin, Sigtou signal stops running)
What do the letters that identify the process mean when we use the Ps-aux command to view the status of the process? , the character of the specific process state is identified as shown in the following table:
Status Flag |
Status Description |
D |
Non-disruptive |
R |
Run |
S |
Interrupt |
T |
Stop it |
Z |
Dead |
However, sometimes we will see some other signs, such as:
Status Flag |
Status Description |
W |
Dead |
< |
High-priority processes |
N |
Low-priority processes |
L |
Memory Lock Page |
See above is interrupted Ah, do not interrupt ah, stop ah, zombie Ah, directly dizzy dead, so how to understand these concepts?
- Running state
In Linux, processes that wait only for CPU time are called ready processes, they are placed in a running queue, and the status flag bit for a ready process is task_running. Once a running process time slice is exhausted, the Linux kernel Scheduler will deprive the process of control of the CPU and choose a suitable process from the running queue to run.
- Sleep Status
There are two process sleep states in Linux:
- One is an interruptible sleep state, its status flag is task_interruptible;
-
Another is the non-interruptible sleep state, Its status flag bit is task_uninterruptible. A process with an interrupted sleep state sleeps until a condition becomes true, such as creating a hardware interrupt, releasing the system resources that the process is waiting for, or passing a signal that can be the condition of the wake process. The non-disruptive sleep state is similar to an interruptible sleep state, but it has one exception: the process of transmitting a signal to this sleep state cannot change its state, meaning it does not respond to the wake of the signal. Non-disruptive sleep states are generally less useful, but in some specific situations this state can be helpful, for example: a process must wait and not be interrupted until a particular event occurs.
When a sigstop signal is sent to the process, it enters the task_stopped state as it responds to the signal (unless the process itself is in a task_uninterruptible state and does not respond to the signal). (Sigstop is very mandatory, as is the Sigkill signal.) The user process is not allowed to reset the corresponding signal handler function through the system call of the signal series. ) sends a SIGCONT signal to the process that can be restored from the task_stopped state to the task_running state.
- Zombie State
The process is in the Task_dead state during the exit process. In this exit process, all the resources that the process occupies will be recycled, in addition to the TASK_STRUCT structure (and a few resources). So the process only left task_struct such an empty shell, so called zombies. The reason for the retention of task_struct is that the exit code of the process, as well as some statistical information, are stored in task_struct. And its parent process is likely to be concerned about this information. In the shell, for example, the $ variable saves the exit code for the last exiting foreground process, and this exit code is often used as a condition for the IF statement.
Of course, the kernel can also store this information elsewhere, freeing the task_struct structure to save some space. However, the use of the TASK_STRUCT structure is more convenient because the kernel has established a relationship between the PID and the Task_struct lookup, as well as the parent-child relationship between processes. Releasing the task_struct, you need to create some new data structures so that the parent process can find the exit information for its child processes.
The parent process can wait for the exit of one or some of the child processes through a system call to the wait series, such as WAIT4, Waitid, and get its exit information. Then the system call of the wait series will also release the Corpse (task_struct) of the child process.
As the child process exits, the kernel sends a signal to its parent process to notify the parent process to "corpse". This signal is SIGCHLD by default, but can be set when a child process is created through the clone system call.
The following code enables the creation of a Exit_zombie State process:
if (fork ()) while (1) sleep (100);
Using Ps-aux, you will see information about a zombie process like the following.
The child process of this zombie state persists as long as the parent process does not exit. So if the parent process exits, who is going to "corpse" the child process?
When the process exits, it will host all its child processes to another process (making it a child of another process). Who's hosting it for? It may be the next process that exits the process group where the process is located, if one exists, or the number 1th process. So every process, every moment, has a parent process present. Unless it is process number 1th.
Summarize
Well, this article sums up a lot of things that you should have learned in college operating system classes. OK, I am in the University operating system class are sleeping, cause now still have to write such an article to review these things, sins, sins.
- This article is from: Linux Tutorial Network
Basic knowledge of Linux process summary