Article directory
- 1. Process status
-
- 1. Running status
- 2. Blocked state
- 3. Suspended state
- 2. Specific process status in Linux
-
- 1. Status in Linux
- 2.R state
- 3.S state
- 4.D state
- 5.T, t state
- 6.X state (dead)
- 7.Z state (zombie)
- 8. Summary of zombie processes
- 9. Summary of orphan processes
1. Process status
In our general operating system disciplines, its process status is: running, blocked, suspended
The new state in the above picture is when a process has just been created, that is, the PCB has just been created.
The termination status means that it is no longer used and the code has been run.
The running state is the state being scheduled.
1. Running status
As shown in the figure below, we know that when our program is running, there are many processes that want to run, but the CPU only has one in extreme scenarios. So there is competition among so many processes. And because of the existence of the scheduler, they can be used in a more balanced way
Therefore, each CPU must maintain its own run queue (struct runqueue), which can schedule these processes.
struct runqueue { //run queue struct task_struct* head; struct task_struct* tail; };
As shown in the figure below, the CPU can directly get a process from the run queue for execution.
This is called processes queuing on the CPU, and the queue is called a run queue.
The scheduler is a function that can pass in the running queue as a parameter, so that all queued processes can be found.
All processes in the run queue are in R state, that is, running state.
The running state means that I am ready and can be scheduled at any time! ! ! As long as it is in the run queue, it is in the running state
When we create a new process, as long as it joins the queue, it will be in the running state. All we have to do is wait for it to be scheduled.
Question: As long as a process puts itself on the CPU and starts running, does it have to be executed until it is put down?
no! Just like the while infinite loop code we wrote earlier.
In order to prevent a certain process from being unable to come down after going up and falling into an infinite loop, each process has the concept of a time slice, which is also a value in the PCB. For example, it is 10ms. Once this 10ms is exceeded, the computer will forcibly remove the process from the CPU and put it at the end of the queue.
So within a period of time, all process code will be executed!
For the above, we also call it concurrent execution.
Therefore, a large number of actions are taken to put processes on and off the CPU – also called process switching.
2. Blocking state
We know that the core of operating system management is to describe first and then organize.
The following is the structure of our operating system
The operating system must manage the following devices and peripherals. It needs to be described first and then organized.
Process management belongs to software, and hardware management can also be done in a similar way.
struct dev { int type; int status; struct task_struct* waitqueue; //............ };
Suppose there is a process whose task is to read data from the keyboard
If we don’t give it input now, it will wait, and it cannot be put into the running state because its current software and hardware resources are not ready.
So it will wait for a certain resource, and in the operating system, it only needs to be put into the waiting queue corresponding to the keyboard.
When there is still data that needs to be input in the future, you will need to queue up at the back.
This is the case for every device.
When our keyboard gives this process data in the future, it will be ready and can enter the run queue, so that the CPU can be scheduled.
So we call this process that is waiting in the queueBlocking state, and each such device has a waiting queue. When the process reads data, it will wake up: change from blocking state to R state
3. Suspended state
We now have a device called a disk
If we currently have multiple processes waiting for the keyboard resource, but the keyboard resource is always ready because no one presses it.
Therefore, these processes can only wait in the waiting queue in a blocked state.
But what if, while waiting, the operating system’s memory resources are seriously insufficient.
Therefore, the operating system needs to save memory resources while ensuring normal operation.
Taking the blocking state as an example, as long as it is not running, the code and data of our current process are actually idle in the memory and are not used.
So at this time, the operating system will reserve the PCBs of these processes and put the code and data into the disk peripherals.
So it is equivalent to this process having only one PCB queued, and its own code and data in the peripheral.
When the process is ready and will be put into the run queue, consider putting the code and data back in.
This process is the process of swapping out and swapping in
If a process only has its own PCB, and the code and data have been swapped out and are not in the memory, then it is in a suspended state
If all processes do this, the operating system will free up a large amount of space in an instant
In fact, the hang we are talking about in the current scenario should be called blocking hang state
Of course, there are also running hangs, ready hangs…etc., we don’t even think about it.
2. Specific process status in Linux
1. Status in Linux
As shown below, it is the status in the Linux system. We can see that there is a big difference from the status mentioned in the previous traditional operating system textbooks.
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 */ };
2.R status
The R state in Linux is the running state
Let’s look at the following code first
When we run it, we can check its running status
We can also run it again
The phenomenon we noticed is that in most cases it is the S state, and in very few cases it is the R state.
Our code is obviously running, but it shows the S state?
Let’s modify the code slightly first
and then running
We can notice that now they are all in R state
So why is this?
This is because we use our own feelings to guess the speed of the CPU
Because we have just been doing printf, we need to access the peripheral (display). Our device may not necessarily be in a direct write state, so our process has a very high probability of waiting.
And after we removed printf, it has been looping rapidly and it has been in the running state.
We can also use the top command, which is equivalent to task management and can check the process at any time.
At the same time, we can also notice that when we used the ps command to view it earlier, there was a + sign after the status. This plus sign means that the process is running in the foreground. (Running in the foreground means that nothing will happen if we continue to enter other commands)
If we want to run a process in the background, we can add an & amp; at the end
We can only kill background processes like this through the kill command.
3.S status
We change the code to the following
At this time, the process we found is most likely in S state.
This is because the CPU is too fast, and this process needs to access peripherals, which seems too slow.
However, we can also use the following example to make it more intuitive
And this state is the same as that in our operating system discipline.
In other words, the S state in Linux is the blocking state in the operating system.
In our operating system, it is generally in a blocking state, that is, waiting for a certain resource to be ready.
So the so-called blocking state is waiting for a certain resource to be ready
Like our previous scanf, it is waiting for keyboard input, and like printf, it is waiting for the monitor to be ready.
4.D status
In Linux, in addition to the S state being a blocking state, there is another state that is also a blocking state, D state, but it is also called deep sleep; and the S state is also called light sleep.
The difference between the two is that S state, that is, light sleep can be awakened
In other words, although the process is still going on, we can use kill to kill him, that is, we can respond to external changes at any time
The one below is in light sleep
Deep sleep cannot be awakened
D state (disk sleep disk sleep)
For example, the following example
Suppose there is a process that wants to write 1GB of data to disk
But this process requires a certain amount of time. During this period of time, the process must wait here for the disk to finish writing all the data and wait for the results to be reflected.
If the memory pressure of the OS is very high at this time, it has now replaced all the resources that can be replaced. Then if the operating system is unhappy with this process, it will kill it directly.
In other words, when the OS memory pressure is very high, some unimportant processes will be killed.
That is, if the OS can handle it, just use the memory. If it can’t handle it, try to replace it. If it still can’t handle it, then you can only kill the process.
At this time, if once the disk write fails and the process is found to have been killed, it will not be able to respond to the process at this time, and the disk will not be able to make a decision. At this time, it depends on the specific hardware. Some hardware will directly discard the data, and some will try to write it again.
If the 1GB of data lost is important, then that’s bad
In order to solve the above problem, we need to ensure that while the process is waiting for the disk writing to be completed, this process cannot be killed by anyone
Therefore, when a process is waiting for the disk to write data, it cannot be set to the S state. It must be set to the D state. The D state cannot be killed by anyone.
When all the data is written, the process returns the D state to the R state.
It also means that if there is only one D state in the operating system, the operating system is about to collapse
The reason why deep sleep cannot be killed is: does not respond to any requests
If we want to simulate it, we can use the dd
command, which can simulate high IO situations.
5.T, t status
The T state is called the pause state, also called the stop state.
We use the following code
When we run it, it is in S state
There is a signal in Linux. As shown below, we used signal No. 9 to kill the process before.
Then here we can send him signals 18 and 19
Process No. 19 SIGSTOP is used to pause a process. If we want to restart it after suspending it, then send signal No. 18 SIGCONT.
As above, it has become a T state. Of course, you can also use signal No. 18 to keep him running.
We can see that if this is paused and then resumed, it will no longer have the + sign, which means it has become a background operation.
So what is the difference between this T state and S state?
In fact, there is, otherwise it would not be divided into two states.
The S state must be waiting for a certain resource to be ready, and the T state can of course wait for a certain resource to be ready after being paused. Of course, it may also be waiting for other events to occur before continuing execution. It does not receive other than certain signals. of other requests. In other words, in T state, it is possible that we just want him to pause for a while.
However, we can temporarily understand him as also being in some kind of blocked state
As shown below, when we use gdb to debug, the program is in t state (we will not distinguish between T and t for the time being)
6.X status (dead)
The so-called X state is the termination state in our previous operating system, which is equivalent to the end of a process.
Then you can put this process into a garbage collection queue, and eventually the operating system will recycle them.
7.Z state (zombie)
When a process dies, it will not immediately enter the X state when it dies, but will first enter the Z state (zombie state)
That is, when a process exits, the operating system will maintain this information for a period of time. This period of time is a zombie state
When a process exits, only the parent process cares most about this information.
We can use the following code to verify. In the following code, the subprocess exits directly after the loop ends. The parent process does not do anything for the child process, which means that once the child process exits, the parent process is still there, but it does nothing, which means that the child process will always remain the same. In a zombie state, it has to wait for the parent process to obtain its exit information
Run this code and the following command simultaneously
while :; do ps ajx | head -1 & amp; & amp; ps ajx | grep mytest;sleep 1; done
The running results are as follows
We can see that when the child process exits, the process is in the Z state, and the word defunct appears later, which means invalid, dead, dead person
This is the process of zombie state
When a process generally exits, if the parent process does not actively recycle the child process information, the child process will keep itself in the Z state, and the related resources of the process, especially the task_struct structure, cannot be released
We also call the process in Z state a zombie process
The memory will always be occupied, and a memory leak will occur
But we still have to pay attention
When we end the program and the parent process, the child process is also exited, and it is not in a zombie state.
This is because when the parent process exits, it also has its own parent process, bash. Bash instantly recycles the parent process, so the parent process is not seen in the zombie state.
The previous case was a case where the child process exited first. We are now looking at a case where the parent process exited first.
The running results are as follows
We found that when the parent process dies, the parent process of its child process becomes 1
So why is this? Let’s first take a look at what process No. 1 is
You can see that it is the system process
That is, process No. 1 is the operating system itself
So we get the following conclusion:
If the parent process exits first, the parent process of the child process will be changed to process No. 1 (operating system)
The parent process is process No. 1. We call this process orphan process
The process is adopted by the system!
So why be adopted?
Because the orphan process will also exit in the future and be released.
So why not let bash adopt?
Bash can’t do it. Bash only creates its child process and cannot manage its grandson process. The operating system can release it directly from the kernel
8. Summary of zombie processes
- The exit status of the process must be maintained because it tells the process that cares about it (the parent process) how I did the task you gave me.
How’s it going? But if the parent process never reads, then the child process will always be in Z state? Yes!- Maintaining the exit status itself requires data maintenance, and it is also the basic information of the process, so it is stored in task_struct (PCB), in other words
Say, the Z state never exits, and the PCB needs to be maintained all the time? Yes!- Which parent process creates many child processes but does not recycle them? Will this cause a waste of memory resources? Yes! Because the data structure
The object itself takes up memory. Think about defining a structure variable (object) in C to open up space at a certain location in the memory.
between!- Memory leak? Yes!
9. Summary of orphan processes
- If the parent process exits early, then the child process exits later and enters Z. What should be done?
- If the parent process exits first, the child process is called an “orphan process”.
- The orphan process is adopted by init process No. 1. Of course, it must be recycled by the init process.