进程在什么情况下会处于状态X(死亡)?

进程在什么情况下会处于状态X(死亡)?

根据fs/proc/array.c:130,以下数组定义了各种进程状态:

/*
 * The task state array is a strange "bitmap" of
 * reasons to sleep. Thus "running" is zero, and
 * you can test for combinations of others with
 * simple bit tests.
 */
static const char * const task_state_array[] = {

    /* states in TASK_REPORT: */
    "R (running)",      /* 0x00 */
    "S (sleeping)",     /* 0x01 */
    "D (disk sleep)",   /* 0x02 */
    "T (stopped)",      /* 0x04 */
    "t (tracing stop)", /* 0x08 */
    "X (dead)",         /* 0x10 */
    "Z (zombie)",       /* 0x20 */
    "P (parked)",       /* 0x40 */

    /* states beyond TASK_REPORT: */
    "I (idle)",         /* 0x80 */
};

根据proc(5),该X状态是在内核2.6.0中添加的:

X Dead(从 Linux 2.6.0 开始)

x Dead(仅限 Linux 2.6.33 至 3.13)

并根据ps(1)X不应该被看到:

X死了(永远不应该被看到)

看看其余的源代码,似乎是这样由内核内部使用。在源文件中kernel/sched.core.c:4176,一条评论简单描述了它:

/*
 * A task struct has one reference for the use as "current".
 * If a task dies, then it sets TASK_DEAD in tsk->state and calls
 * schedule one last time. The schedule call will never return, and
 * the scheduled task must drop that reference.
 *
 * We must observe prev->state before clearing prev->on_cpu (in
 * finish_task), otherwise a concurrent wakeup can get prev
 * running on another CPU and we could rave with its RUNNING -> DEAD
 * transition, resulting in a double drop.
 */

看来也是必需的在某些情况下。在kernel/fork.c:424:

static void release_task_stack(struct task_struct *tsk)
{
    if (WARN_ON(tsk->state != TASK_DEAD))
        return;  /* Better to leak the stack than to free prematurely */

    account_kernel_stack(tsk, -1);
    free_thread_stack(tsk);
    tsk->stack = NULL;
#ifdef CONFIG_VMAP_STACK
    tsk->stack_vm_area = NULL;
#endif
}

在我看来,它就像是TASK_DEAD在进程终止时但在内核最终销毁之前为进程设置的task_struct,因此它永远不应该显示为进程状态,除非存在无法清理进程的内核错误。还有这些讲义这强化了这个想法:

TASK_DEAD – 进程正在被清理并且任务正在被删除

所以我真正的问题是:

在什么情况下进程会被报告为ps处于状态 X?

答案1

“X”代表的任务状态不是TASK_DEAD,而是退出EXIT_DEAD状态TASK_DEAD本身不是应报告国家,而同时EXIT_DEAD是,它在实践中不应该是可见的

EXIT_DEAD的角色与您所描述的类似TASK_DEAD:任务的退出状态设置为在其被删除之EXIT_DEAD前不久;参见例如task_structrelease_taskde_thread,release_task本身, 和exit_notify

我还没有详细检查锁定,并且读者可以看到改变的进程状态;然而,一个进程似乎不太可能被EXIT_DEAD另一个进程看到其状态。

无论是否可见,进程一旦完全退出并且即将task_struct被删除,就处于状态“X”。

相关内容