In addition to running, dormant... the process actually has a zombie and orphan state

Abstract: In this chapter we will recognize several process states - running state, dormant state, paused state, exit state, etc. Also introduce two zombie processes and orphan processes with tragic life experiences~

This article is shared from Huawei Cloud Community " Zombie Process? Orphan process? Why did he have such a tragic life experience... ", author: Hua Xiangyun.

Know the state of the process

The process status in Linux generally has:

  • R (running state): It does not mean that it is actually running (referring to being scheduled by the CPU);
  • S (sleep state): The process is waiting to acquire some kind of resource, this state is also called interruptible sleep;
  • D (disk dormancy state): The process in this state is also dormant, but cannot be interrupted, so this state is also called uninterruptible dormancy;
  • T (Suspend state): A process can be stopped by sending a SIGSTOP signal to the process. The suspended process can be resumed by sending the SIGCONT signal.
  • X (Death state): This state is just a return state, you will not see this state in the task list;
  • Z (zombie state): When a child process is not "recycled" by the parent process, the process will be in the zombie state;

The following is the definition of these states in the kernel source code:

static const char * const task_state_array[] = {
“R (running)”, // 0
“S (sleeping)”, // 1
“D (disk sleep)”, // 2
“T (stopped)”, // 4
“t (tracing stop)”, // 8
“X (dead)”, // 16
“Z(zombie)”, // 32
};

How to check process status

  • Enter the command:
ps axj | head -n1 && ps axj | grep myprocess | grep -v grep

Next, let's take a look at what the various states look like~

R state

Citation

When you run many programs on your computer at the same time, for example, when you are typing code, you are also listening to a song played by a certain software, or switching back and forth between browsers. Are all these applications running on the CPU at this time?

The answer is, not really.

When the CPU is working, there will be a queue of processes running. The content maintained by the queue is a pointer to each task_struct structure (it was mentioned in the previous chapter that task_struct is a process descriptor). The processes maintained in this queue are all in the R state and waiting to be scheduled by the CPU.

how to observe

Write a simple piece of code:

#include<stdio.h>
#include<unistd.h>
int main()
{
 while(1)
 {
 printf("hello myprocess\n");
 }
 return 0;
}

After running the program, view the status of the process as shown in the figure:

  • Here comes the question again, why did not see the so-called R state when the program was executed?
  • The answer is, because the CPU operation speed is too fast, it is basically difficult for us to see the R state. The process prints hello myprocess on the screen in an endless loop. We all know that the screen at this time is a kind of peripheral, and the computing speed of the CPU is not in the same order of magnitude as the access speed of the peripheral. Therefore, the process prints content on the screen in an endless loop, accessing peripherals 99.9% of the time, and the rest of the time is CPU doing calculations. When a process accesses peripherals, the CPU will not wait in place, but turn around and do other things. When the process successfully accesses the peripherals, the CPU will schedule it.

So is there any way to wait to see the R status? We slightly modify the code above:

#include<stdio.h>
#include<unistd.h>
int main()
{
 while(1)
 {
 //printf("hello myprocess\n");
 }
 return 0;
}

As shown in the figure above, when we no longer access the peripherals, but just keep doing repeated calculations, the CPU will always be scheduled at this time, and we can see the R state.

S state and D state

S state

The S state is called the sleep state. Why should a process sleep well? Is it because you are tired from running for too long? Of course not. Sleep state is essentially a kind of blocking.

  • Blocking: A state in which a process is not advancing because it is waiting for a resource to become available.

For example, when a process is halfway running and needs to obtain a large piece of data from the disk, it will take a long time. At this time, the processing method of the OS is to let the process continue to wait for the data it wants, but you are required not to occupy the CPU while waiting for resources, so the process is arranged by the OS to wait somewhere. It is in the S state.

how to observe

#include<stdio.h>
#include<unistd.h>
int main()
{
 while(1)
 {
 int n = 0;
 scanf("%d",&n);
 printf("%d\n",n);
 }
 return 0;
}

As shown in the diagram above, when a process is waiting for data entered by the user from the keyboard, it sleeps.

D state

The D state is also a hibernation state, but it has another name called disk hibernation state or uninterruptible hibernation. So how do you view the difference between the S state and the D state?

First of all, we have to understand under what circumstances the process will be interrupted. When a process does some bad things secretly, and the user wants to stop the process at this time, he must send an interrupt signal to the process, and the process will be "killed".

In some cases, the OS can "kill" certain processes by itself without the need for the user to do it himself. For example, when memory resources are very tight or even endanger the safety of the entire system, the OS will "kill" some unimportant processes.

For example, a certain process enters a dormant state because it is waiting for data. At this time, it is discovered by the OS. If the memory is so tight, are you still sleeping here? Fork out! Well, the process was forked out. At this time, half of the data was read, and the party concerned disappeared. These data can only be discarded, otherwise whoever finds the process just now can find "me" after reincarnation.

If these discarded data are some irrelevant data, just throw them away. But if it is a confidential document, wouldn't it be a big deal? Therefore, in order to prevent some uninterruptible processes from being accidentally killed by the OS, the process can be placed in an uninterruptible sleep state, that is, the D state. At this time, the process is finally not afraid of being disturbed when it is sleeping, but each step back, I will sleep in another place, otherwise I am afraid that you will be impatient. So when the process sleeps, it goes to sleep on a relatively wide disk.

T state

The T state is called the stop state, which is very easy to understand. It means to pause a certain process. For example when debugging, we set several breakpoints. When the process stops at the breakpoint, the process is suspended.

how to observe

method one

#include<stdio.h> 
#include<unistd.h>
int main() 
{ 
 while(1) 
 { 
 //printf("hello myprocess\n"); 
 int n = 0; 
 scanf("%d",&n); printf("%d\n",n); 
 }
 return 0;
}

When we set a breakpoint on line 9 and run it, the program stops at the breakpoint. Check the process status at this time as shown in the figure below:

Note: t is also a suspended state. Sometimes also called tracking state.

Method Two

We can put a process into a paused state by sending a pause signal to the process. Edit the following code:

#include<stdio.h> 
#include<unistd.h>
int main() 
{ 
 while(1) 
 { 
 printf("hello myprocess\n"); 
 }
 return 0;
}

When the program starts running, send a pause signal to the process at this time:

$ kill -19 (进程PID)

In addition, we can also send a continue signal to allow the process to continue executing:

$ kill -18 (进程PID)

Notice

The process continues to run. But we found that there is one place that seems to be different from before. Is there always a + sign behind the S? We don't know what + is for, only that he seems to have disappeared now.

  • "+" means running in the foreground, without "+" means running in the background;

We used to use Ctrl + c when terminating a program before, but now it seems that it is invalid for the process running in the background. At this time, we need to master a new command to "kill" the process:

$ kill -9 (进程PID)

or,

$ kill -9 (进程PID)

X state and Z state

  • The X state is an exit state, which is a transient state that is not easy to observe, and it is considered unimportant for the time being;
  • The Z state is called the Zombie state. As the name implies, a process that dies (exits) but does not "collect the body" becomes a "zombie". Specifically, when a process exits, if its parent process does not read the exit status code returned when the process exits, the process will become a zombie process.

There are a lot of concepts, so let's talk about them first. First of all what is the exit status code? In a C language program, we often have to write a line of code at the end of the main function - return 0;. This 0 is the exit status code, but it is not just 0, it can also be 1, 2, 3...

How to see zombie processes?

Next, let's write a piece of code to see the zombie process:

#include<stdio.h> 
#include<unistd.h>
int main() 
{
 pid_t id = fork();
 if(id == 0)
 {
 while(1)
 {
 printf("我是子进程,我在运行,pid:%d,ppid:%d\n",getpid(),getppid());
 sleep(1);
 }
 }
 else if(id > 0) 
 {
 while(1)
 {
 printf("我是父进程,我在运行,pid:%d,ppid:%d\n",getpid(),getppid());
 sleep(1);
 }
 }
 return 0;
}

When we run the program, we can see that the program is running normally;

At this time, when we execute the command to "kill" the child process, the child process will become a zombie process;

$ kill -9 (子进程PID)

Among them, we can see an English word-defunct means zombie.

The dangers of zombie processes

  • Maintaining the exit status itself requires data maintenance, which also belongs to the basic information of the process, so it is stored in the task_struct (ie PCB). In other words, the Z state does not exit all the time, and the PCB has to be maintained all the time.
  • A parent process creates many child processes, but if it is not recycled, it will cause a waste of memory resources. Because the data structure object itself takes up memory.

Zombie processes are harmful, and of course we can avoid them, which needs to be mentioned in the next chapter.

orphan process

When the parent process is alive, the child process hangs up early, which is easy to cause a zombie process. So if the parent process hangs up early, where should the child process go? This is the orphan process we are going to talk about next.

How to see orphaned processes

Edit the following code:

#include<stdio.h> 
#include<unistd.h>
int main() 
{
 pid_t id = fork();
 if(id == 0)
 {
 while(1)
 {
 printf("我是子进程,我在运行,pid:%d,ppid:%d\n",getpid(),getppid());
 sleep(1);
 }
 }
 else if(id > 0) 
 {
 while(1)
 {
 printf("我是父进程,我在运行,pid:%d,ppid:%d\n",getpid(),getppid());
 sleep(1);
 }
 }
 return 0;
}

Run the program, we use the kill command to "kill" the parent process, and then check the process information:

As shown in the figure above, two changes have occurred in the child process. One is the PPID of the child process, and the other is that the child process becomes running in the background.

how to understand

When the parent process of the child process hangs up, the child process will be adopted by process 1. This process is also known as an orphan process.

  • So why adopt?

The answer is to find someone to collect the body for yourself. Otherwise, when I suddenly die one day and no one collects my body for me, it will become a zombie process that will cause disaster to the world.

 

Click to follow and learn about Huawei Cloud's fresh technologies for the first time~

{{o.name}}
{{m.name}}

おすすめ

転載: my.oschina.net/u/4526289/blog/9429287