Home  >  Article  >  Operation and Maintenance  >  There are several states of linux processes

There are several states of linux processes

青灯夜游
青灯夜游Original
2023-03-13 10:11:248422browse

Linux process has 6 states: 1. R executable state, only processes in this state can run on the CPU; 2. S interruptible sleep state, processes in this state are waiting for something The event occurs and is suspended; 3. D uninterruptible sleep state, the process is in sleep state, but the process is uninterruptible at this moment; 4. T pause state or tracking state, send a SIGSTOP signal to the process, and it will Entering the T state in response to this signal; 5. Z zombie state, indicating that a process is about to die; 6. X death state.

There are several states of linux processes

#The operating environment of this tutorial: linux7.3 system, Dell G3 computer.

In Linux, a process has 6 states, namely: executable state, interruptible sleep state, uninterruptible sleep state, suspended state or tracking state, zombie state and my death state.

Linux process status detailed explanation

R(TASK_RUNNING) executable status

Only in this Only processes in this state may run on the CPU. There may be multiple processes in the executable state at the same time, and the task_struct structures (process control blocks) of these processes are put into the executable queue of the corresponding CPU (a process can only appear in the executable queue of one CPU at most). The task of the process scheduler is to select a process from the executable queue of each CPU to run on that CPU.

Many operating system textbooks define processes that are executing on the CPU as the RUNNING state, and processes that are executable but have not yet been scheduled for execution as the READY state. These two states are unified into the TASK_RUNNING state under Linux.

S(TASK_INTERRUPTIBLE) Interruptible sleep state

The process in this state is waiting for a certain event to occur (such as waiting for a socket connection, waiting for a semaphore), And was suspended. The task_struct structures of these processes are put into the waiting queue of the corresponding events. When these events occur (triggered by external interrupts or triggered by other processes), one or more processes in the corresponding waiting queue will be awakened.

Through the ps command, we will see that, under normal circumstances, the vast majority of processes in the process list are in the TASK_INTERRUPTIBLE state (unless the load on the machine is very high). After all, there are only one or two CPUs, and there are often dozens or hundreds of processes. If not most of the processes are sleeping, how can the CPU respond?

D(TASK_UNINTERRUPTIBLE) Uninterruptible sleep state

Similar to the TASK_INTERRUPTIBLE state, the process is in a sleep state, but the process is uninterruptible at this moment. Uninterruptible does not mean that the CPU does not respond to interrupts from external hardware, but that the process does not respond to asynchronous signals.

In most cases, the process should always be able to respond to asynchronous signals when it is in sleep state. Otherwise, you will be surprised to find that kill -9 cannot kill a sleeping process! So we can also easily understand why the processes seen by the ps command rarely appear in the TASK_UNINTERRUPTIBLE state, but always in the TASK_INTERRUPTIBLE state.

The significance of the TASK_UNINTERRUPTIBLE state is that certain processing flows of the kernel cannot be interrupted. If you respond to an asynchronous signal, a process for processing asynchronous signals will be inserted into the execution flow of the program (this inserted process may only exist in the kernel mode, or may extend to the user mode), so the original process will be interrupted. .

When the process operates on certain hardware (for example, the process calls the read system call to read a certain device file, and the read system call eventually executes the code of the corresponding device driver and communicates with the corresponding physical device interaction), you may need to use the TASK_UNINTERRUPTIBLE state to protect the process to prevent the interaction between the process and the device from being interrupted, causing the device to fall into an uncontrollable state. The TASK_UNINTERRUPTIBLE state in this case is always very short-lived and basically impossible to capture through the ps command.

There is also a TASK_UNINTERRUPTIBLE state that is easy to capture in Linux systems. After executing the vfork system call, the parent process enters the TASK_UNINTERRUPTIBLE state until the child process calls exit or exec.

T(TASK_STPPED or TASK_TRACED) Suspend state or trace state

Send a SIGSTOP signal to the process, and it will enter the TASK_STOPPED state in response to the signal (unless the The process itself is in the TASK_UNINTERRUPTIBLE state and does not respond to signals). (SIGSTOP, like the SIGKILL signal, is very mandatory. The user process is not allowed to reset the corresponding signal processing function through the signal series system call.)

Send a SIGCONT signal to the process to change it from the TASK_STOPPED state Restore to TASK_RUNNING state.

When a process is being traced, it is in the special state of TASK_TRACED. "Being tracked" means that the process is paused and waiting for the process that is tracking it to operate on it. For example, if you set a breakpoint on the tracked process in gdb, the process will be in the TASK_TRACED state when it stops at the breakpoint. At other times, the tracked process is still in the states mentioned earlier.

For the process itself, the TASK_STOPPED and TASK_TRACED states are very similar, both indicating that the process is suspended.

The TASK_TRACED state is equivalent to an additional layer of protection on top of TASK_STOPPED. The process in the TASK_TRACED state cannot be awakened in response to the SIGCONT signal. The debugged process can only return to the TASK_RUNNING state until the debugging process performs operations such as PTRACE_CONT and PTRACE_DETACH through the ptrace system call (the operations are specified through the parameters of the ptrace system call), or the debugging process exits.

Z(TASK_DEAD - EXIT_ZOMBIE) Zombie state, the process becomes a zombie process

The process is in the TASK_DEAD state during the exit process.

During this exit process, all resources occupied by the process will be recycled, except for the task_struct structure (and a few resources). So the process is left with only the empty shell of task_struct, so it is called a zombie.

The reason why task_struct is retained is because task_struct stores the exit code of the process and some statistical information. And its parent process is likely to care about this information. For example, in the shell, the $? variable stores the exit code of the last foreground process that exited, and this exit code is often used as the judgment condition of the if statement.

Of course, the kernel can also save this information elsewhere and release the task_struct structure to save some space. However, it is more convenient to use the task_struct structure, because the search relationship from pid to task_struct has been established in the kernel, as well as the parent-child relationship between processes. To release the task_struct, you need to create some new data structures so that the parent process can find the exit information of its child process.

The parent process can wait for the exit of one or some child processes through the wait series of system calls (such as wait4, waitid) and obtain its exit information. Then the wait series of system calls will also release the body of the child process (task_struct).

When the child process exits, the kernel will send a signal to its parent process to notify the parent process to "collect the corpse". This signal defaults to SIGCHLD, but this signal can be set when creating a child process via the clone system call.

As long as the parent process does not exit, the child process in this zombie state will always exist. So if the parent process exits, who will "collect the corpse" of the child process?

When a process exits, all its child processes will be hosted by other processes (making them child processes of other processes). Who is entrusted to? This may be the next process in the process group of the exiting process (if one exists), or process number 1. So every process and every moment has a parent process. Unless it's process number 1.

Process No. 1, the process with pid 1, is also called the init process. After the Linux system starts, the first user mode process created is the init process. It has two missions:

  • Execute the system initialization script and create a series of processes (all of them are descendants of the init process);

  • Wait for the exit event of its child process in an infinite loop, and call the waitid system call to complete the "corpse collection" work;

init process will not be suspended or killed (This is guaranteed by the kernel). It is in the TASK_INTERRUPTIBLE state while waiting for the child process to exit, and is in the TASK_RUNNING state during the "recovery" process.

X(TASK_DEAD - EXIT_DEAD) Death state, the process is about to be destroyed

And the process may not retain its task_struct during the exit process. For example, this process is a detachable process in a multi-threaded program.

Or the parent process explicitly ignores the SIGCHLD signal by setting the handler of the SIGCHLD signal to SIG_IGN. (This is a POSIX specification, although the exit signal of the child process can be set to a signal other than SIGCHLD.)

At this point, the process will be placed in the EXIT_DEAD exit status, which means that the following code immediately The process will be completely released. So the EXIT_DEAD state is very short-lived and almost impossible to capture with the ps command.

The initial state of the process

The process is created through the fork series of system calls (fork, clone, vfork), the kernel (or Kernel module) can also create a kernel process through the kernel_thread function. These functions that create subprocesses essentially perform the same function - copy the calling process to obtain a subprocess. (You can decide whether various resources are shared or private through option parameters.)

So since the calling process is in the TASK_RUNNING state (otherwise, if it is not running, how can it be called?), the child process is also in the TASK_RUNNING state by default. In addition, the system call clone and kernel function kernel_thread also accept the CLONE_STOPPED option, thereby setting the initial state of the child process to TASK_STOPPED.

Process status changes

After the process is created, the status may undergo a series of changes until the process exits. Although there are several process states, there are only two directions for process state changes - from TASK_RUNNING state to non-TASK_RUNNING state, or from non-TASK_RUNNING state to TASK_RUNNING state.

In other words, if a SIGKILL signal is sent to a process in the TASK_INTERRUPTIBLE state, the process will first be awakened (enter the TASK_RUNNING state), and then exit in response to the SIGKILL signal (change to the TASK_DEAD state). It will not exit directly from the TASK_INTERRUPTIBLE state.

The process changes from the non-TASK_RUNNING state to the TASK_RUNNING state by other processes (which may also be interrupt handlers) performing wake-up operations. The process that performs the awakening sets the status of the awakened process to TASK_RUNNING, and then adds its task_struct structure to the executable queue of a CPU. Then the awakened process will have the opportunity to be scheduled for execution.

There are two ways for the process to change from the TASK_RUNNING state to the non-TASK_RUNNING state:

  • In response to the signal, it enters the TASK_STOPED state or the TASK_DEAD state;

  • Execute system calls to actively enter the TASK_INTERRUPTIBLE state (such as nanosleep system calls), or TASK_DEAD states (such as exit system calls); or enter the TASK_INTERRUPTIBLE state or because the resources required to execute system calls cannot be met. TASK_UNINTERRUPTIBLE status (such as select system call).

Obviously, both of these situations can only occur while the process is executing on the CPU.

Linux process status description

##Status symbolFull name of statusDescriptionRTASK_RUNNINGExecutable status & running status (status in the run_queue queue) STASK_INTERRUPTIBLEInterruptible sleep state, can handle signalDTASK_UNINTERRUPTIBLEUninterruptible sleep state, signal can be processed, with delay##TZ
TASK_STOPPED or TASK_TRACED In the pause state or tracking state, the signal cannot be processed because there is no time slice to run the code
TASK_DEAD - EXIT_ZOMBIE Exit status, the process becomes Zombie process. Cannot be killed, that is, does not respond to task signals, cannot be killed with SIGKILL
Extended knowledge: What is a waiting queue, what is a running queue, and what is a hang /Blocking, what is waking up the process? Being scheduled by the CPU is called waking up the process

When a process is running, because some of its operating conditions are not ready yet (for example, the network is required but the network card is not available, or it needs to wait for IO, that is, it needs to use peripherals ), it will be placed in the waiting queue, and the status bit in task_struct will also be changed to S/D.

When the process is in the S/D state, it is waiting in a waiting queue to use peripherals (such as network cards, disk monitors, etc.)

The queue waiting for the CPU is called the run queue. The device we set up is called the waiting queue

The so-called process, when running, may be in different queues due to operational needs

In different queues, the status is It's different

When a process is in the R state, if a certain peripheral is needed but the peripheral is being used, I will change your state to S/D, and then change your task_struct Put it in the waiting queue

Related recommendations: "

Linux Video Tutorial

"

The above is the detailed content of There are several states of linux processes. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn