Linux process state (PS STAT) R, S, D, T, Z, X

Recommended for you: Get network issues from WhatsUp Gold. Not end users.

Linux is a multi-user, multi tasking system, you can run multiple program multiple users at the same time, we will have many processes, each process will have a different state.

Linux process state: R (TASK_RUNNING), executable state.

Only in the state of the process can run in CPU. At the same time more than one process may be in the executable state, task_struct structure of these processes (process control block) is placed into the corresponding CPU executable queue (a process can only occur in a CPU executable queue). The process scheduler task is from the CPU executable queue respectively select a process running on the CPU.

The process of defining many textbooks will perform the operating system on CPU RUNNING state, the executable process definitions but has not yet been scheduled for execution to the READY state, the two state of unity to the TASK_RUNNING state in Linux.

Linux process state: S (TASK_INTERRUPTIBLE), can interrupt sleep state.

In this state the process because of waiting for certain events (such as waiting for a socket connection, waiting for the signal quantity), and be hanged. The task_struct structure of these processes were in the corresponding event wait queue. When these events occur (interrupt trigger, or a trigger by other processes by external), corresponding wait for one or more processes in the queue will be awakened.

The PS command we will see that, in general, the process of the list in the vast majority of process in the TASK_INTERRUPTIBLE state (unless the machine load is high). After all, CPU was one or two, the process frequently dozens, hundreds, if not most processes in CPU sleep, and how to respond to come over.

Linux process state: D (TASK_UNINTERRUPTIBLE), can not be interrupted sleep state.

With TASK_INTERRUPTIBLE similar state, process in a sleep state, but this process is not interrupted. Don't interrupt, does not mean CPU not interrupt external hardware, but that does not respond to asynchronous signal process.
The vast majority of cases, the process is in the sleep state, should always be able to respond to asynchronous signals. Otherwise, you will be surprised to find that, kill -9 didn't kill a sleeping process! So we have a good understanding of why the PS command, see the process is almost no TASK_UNINTERRUPTIBLE state, TASK_INTERRUPTIBLE state and always.

The TASK_UNINTERRUPTIBLE state is the meaning of existence, some processes of the kernel is not interrupted. If the response asynchronous signal, will the execution flow of a program by inserting a for processing asynchronous signal process (the insertion process may exist only in kernel mode, may also extend to the user state), then the original process flow is interrupted. (see "Linux kernel asynchronous interrupt analysis )
Operate on some hardware in the process (such as process invokes the read system call to read operations on a device file, While the read system call final execution to the corresponding device driver code, And interact with the physical device corresponding), May protect the process needs to use the TASK_UNINTERRUPTIBLE state, Interrupted to process to avoid interaction process and equipment, Cause equipment into uncontrollable state. In this case the TASK_UNINTERRUPTIBLE status is always very short, through the PS command basically impossible to capture.

Easy to capture TASK_UNINTERRUPTIBLE state also exist in Linux systems. Implementation of the VFORK system call, the parent process will enter a TASK_UNINTERRUPTIBLE state, until the child process called exit or exec (see "magic VFORK ).
Be in the TASK_UNINTERRUPTIBLE state process through to the following code:

  1. #include
  2. void main() {
  3. if (!vfork()) sleep(100);
  4. }

Compile and run, and then PS:

  1. kouu@kouu-one:~/test$ ps -ax | grep a\.out
  2. 4371 pts/0 D+ 0:00 ./a.out
  3. 4372 pts/0 S+ 0:00 ./a.out
  4. 4374 pts/1 S+ 0:00 grep a.out

Then we can test the TASK_UNINTERRUPTIBLE state power. Both kill and kill -9, the TASK_UNINTERRUPTIBLE state of the parent process still fail.

Linux process state: T (TASK_STOPPED or TASK_TRACED), a suspended state or tracking state.

To process an SIGSTOP signal is sent, it will result in response to the signal into the TASK_STOPPED state (unless the process itself is in the TASK_UNINTERRUPTIBLE state without response signal). (SIGSTOP and SIGKILL signal, is mandatory. The signal processing function does not allow the user to process through the system call signal to set the corresponding. )
Sending a SIGCONT signal to a process, can make its recovery from the TASK_STOPPED state to the TASK_RUNNING state.

When the process is being followed, it is TASK_TRACED this special status. "Being followed by the "refers to the process to pause, wait for tracking its process to operate it. For example, in GDB the tracking process under a breakpoint, the process stops at the breakpoint is in the TASK_TRACED state. At other times, followed by the process or in those states mentioned.

For the process itself, TASK_STOPPED and TASK_TRACED state is very similar, is a process to pause.
But the TASK_TRACED state is equivalent to a layer of protection in TASK_STOPPED, in the TASK_TRACED state of the process can not response to the SIGCONT signal and wake up. Only when the debugging process in the implementation of PTRACE_CONT, PTRACE_DETACH through the ptrace system call operation (operation parameters specified by ptrace system call), or debugging process, has been debugging process to recover the TASK_RUNNING state.

Linux process state: Z (TASK_DEAD - EXIT_ZOMBIE), the exit status, process become a zombie.

In the process of exit, is in the TASK_DEAD state.

In the process of withdrawal, all process resource possession will be recycled, in addition to the task_struct structure (and a few other resources). So the process is only task_struct such a shell, it is known as the zombie.
The retention of task_struct, because task_struct is saved inside process exit code, and some statistical information. But the parent process is likely to care about these information. For example, in shell, $? Variable will save the last exit foreground process exit code, and the exit code is often as the judgment condition of the if statement.
Of course, the kernel can also store the information in other places, and the structure of task_struct release, in order to save some space. But the use of task_struct structure is more convenient, because in the kernel has been established from PID to task_struct to find relationship, as well as the process of parent-child relationships between. Release the task_struct, you need to establish some new data structure, so that the parent process to find its Zi Jincheng exit information.

The parent process through the system call wait series (such as wait4, waitid) for one or more of the child process exit, and obtains its exit information. Then the system call wait series of by the way the child process's body (task_struct) also release.
The child process in the process of exit, the kernel will send a signal to the parent process, notify the parent process to "bury the dead". This signal is SIGCHLD by default, but in the creation of the clone system call process, you can set the signal.

The following code to create an EXIT_ZOMBIE state process:

  1. #include
  2. void main() {
  3. if (fork())
  4. while(1) sleep(100);
  5. }

Compile and run, and then PS:

  1. kouu@kouu-one:~/test$ ps -ax | grep a\.out
  2. 10410 pts/0 S+ 0:00 ./a.out
  3. 10411 pts/0 Z+ 0:00 [a.out]
  4. 10413 pts/1 S+ 0:00 grep a.out

As long as the parent process does not exit, the zombie sub process has been the existence of. If the parent process exit, who came to the child process "to accept corpse"?
When the process exits, will all child processes which are managed to another process (as in other process Zi Jincheng). Managed to who? May be withdraw from the process where the process group under a process (if present), or the 1 process. So every process, every time the parent process exits. Unless it is No. 1 process.

No. 1, PID 1, also known as the init process.
The Linux system after the start, the first to be created a user mode process is init process. It has two mission:
1, Implementation of the system initialization scripts, creating a series of processes (they are the descendants of the init process),
2, Wait for the child process in an infinite loop exit events, and a waitid system call to complete the "body",
The init process will not be suspended, would not be killed (this is used by the kernel to guarantee). It is in the TASK_INTERRUPTIBLE state in the process of waiting for the child process exit, "is in the TASK_RUNNING state in the process of collecting bodies".

Linux process state: X (TASK_DEAD - EXIT_DEAD), the exit status, the process is about to be destroyed.

The process in the exit process may not retain its task_struct. For example, this process is multithreaded program is detach process (thread process?? see "Linux thread analysis ). Or the parent process by setting the SIGCHLD signal handler SIG_IGN, explicitly ignores SIGCHLD signal. (this is the provisions of POSIX, as the process exit signals can be set to other signals other than SIGCHLD. )
At this point, the process will be under the EXIT_DEAD out of state, this means that the next code immediately will complete the release of the process. So the EXIT_DEAD state is very short, almost impossible to capture by the PS command.

The initial state of a process

The process is through the system call fork series (fork, clone, VFORK) to create, the kernel (or kernel module) can also create kernel process by kernel_thread function. Function nature of these create the child process is complete the same functions -- will be a copy of the calling process, get the child process. (the option of parameters to determine the various resources are shared, or private. )
So now that the calling process in the TASK_RUNNING state (or, if it is not running, and how to call?), then the child process is in the TASK_RUNNING state by default.
In addition, the CLONE_STOPPED option is accepted in the system call clone and kernel function kernel_thread, which will be the initial state of the child process is set to TASK_STOPPED.

The process of the state transition

Since the process of creating, may produce a series of changes, until the process exits. And although the process has several, but change process state but only two direction -- from the TASK_RUNNING state to the non TASK_RUNNING state, or from a non TASK_RUNNING state to the TASK_RUNNING state.
That is to say, if the sending SIGKILL signal process in a TASK_INTERRUPTIBLE state, the process will be awakened (in the TASK_RUNNING state), and then the response SIGKILL signal and exit (to the TASK_DEAD state). Do not withdraw from the TASK_INTERRUPTIBLE state.

Process from the non TASK_RUNNING state to the TASK_RUNNING state, by another process (and possibly the interrupt handler) executing wake-up to achieve. Implementation of awakening process is set wake-up process state is TASK_RUNNING, then the task_struct structure into a CPU executable queue. So the awakened process will have the chance to be scheduled for execution.

The process from the TASK_RUNNING state to the non TASK_RUNNING state, there are two ways:
1, In response to the signal into the TASK_STOPED state, or the TASK_DEAD state,
2, Executing the system call active into the TASK_INTERRUPTIBLE state (such as the nanosleep system call), or TASK_DEAD (such as exit system call); or as a result of the implementation of system call requires resources do not meet, Enter the TASK_INTERRUPTIBLE or TASK_UNINTERRUPTIBLE state (such as the select system call).
Obviously, these two kinds of circumstances can only occur in the process of implementation is the case of the CPU.

The kernel module code:
--—-killd.c--—-
#include #include #include //for_each_process
MODULE_LICENSE("BSD");
static int pid = -1;
module_param(pid, int, S_IRUGO);
static int killd_init(void)
{
struct task_struct * p;
printk(KERN_ALERT "killd: force D status process to death\n");
printk(KERN_ALERT "killd: pid=%d\n", pid);
//read_lock(&tasklist_lock);
for_each_process(p){
if(p->pid == pid){
printk("killd: found\n");
set_task_state(p, TASK_STOPPED);
printk(KERN_ALERT "killd: aha, dead already\n");
return 0;
}
}
printk("not found");
//read_unlock(&tasklist_lock);
return 0;
}
static void killd_exit(void)
{
printk(KERN_ALERT "killd: bye\n");
}
module_init(killd_init);
module_exit(killd_exit);
—–Makefile--
obj-m := killd.o
Compiler module
make -C yourkerneltree M=`pwd` modules
When the insertion module provides the D state of the process, you can convert it to a stopped state, using the common kill can kill.
./insmod ./killd.ko pid=1234

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Posted by Demi at July 22, 2014 - 4:02 AM