【问题标题】:Zombie process even though threads are still running僵尸进程,即使线程仍在运行
【发布时间】:2015-01-15 18:03:53
【问题描述】:

为什么Linux认为主线程已经终止的进程是僵尸进程,有什么办法可以避免这种情况?

在下面的代码中:

  1. 创建一个只有一个主线程的进程
  2. 创建一个新的分离线程
  3. pthread_exit主线程
  4. pthread_exit分离的线程

在#3 之前,ps(1) 将我的进程显示为正常进程。然而,在 #3 之后,ps(1) 将我的进程显示为僵尸(例如,2491 pts/0 00:00:00 thread-app <defunct>即使它仍然有正在运行的线程。

是否可以退出主线程但避免进入僵尸状态?

代码:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>

void *thread_function(void *args)
{
printf("The is new thread! Sleep 20 seconds...\n");
sleep(20);
printf("Exit from thread\n");
pthread_exit(0);
}

int main(int argc, char **argv)
{
pthread_t thrd;
pthread_attr_t attr;
int res = 0;
res = pthread_attr_init(&attr);
res = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
res = pthread_create(&thrd, &attr, thread_function, NULL);
res = pthread_attr_destroy(&attr);
printf("Main thread. Sleep 5 seconds\n");
sleep(5);
printf("Exit from main process\n");
pthread_exit(0);
}

# ./thread-app

【问题讨论】:

  • 也许你想要ptherad_join()
  • 我想要一个新线程,它比原来的主线程寿命更长。并且该主线程被正确销毁,没有成为僵尸。
  • @likern,我对您的帖子进行了大量编辑,但我认为它更好地反映了您的问题。如果您不同意,则回滚编辑。
  • 我认为原因是主线程和新线程共享内存,主线程拥有的数据可以被新线程使用 - 因此即使在主线程完成工作后也无法释放。由于这个原因,主线程被设置为僵尸状态。
  • @likern,根据 posix 标准,您是正确的。我认为 Linux 正在使用父线程来跟踪所有 pthread 信息。 pthread_exit 知道并保留该进程,而不是对其调用等待。在 linux 中,可能无法按照您的要求进行操作。我的一般编码策略是让主线程保持活动状态,直到所有子线程都消失,以避免出现未定义状态,所以直到你提出来我才看到。

标签: c linux multithreading pthreads posix


【解决方案1】:

这是一个已知问题。不久前 Kaz 的 fix proposed 未被 Ulrich Drepper 接受。他对此的评论是:

I haven't looked at the patch nor tried it.

If the patch changes the behavior that the main thread, after calling
sys_exit, still react to signals sent to this thread or to the process
as a whole, then the patch is wrong. The userlevel context of the
thread is not usable anymore. It will have run all kinds of
destructors. The current behavior is AFAIK that the main thread won't
react to any signal anymore. That is absolutely required.

在此处阅读邮件链以获取更多讨论:

http://lkml.iu.edu/hypermail/linux/kernel/0902.0/00153.html

【讨论】:

    【解决方案2】:

    操作系统认为您的进程是僵尸进程,因为由操作系统启动的主线程返回(即退出)。如果你不想要这种行为,那么不要让主线程退出。

    【讨论】:

    • 我要补充一点,这是一个名义上的僵尸(“nombie”?)。当其他线程正在运行时,通过pthread_exit 终止主线程不会生成 SIGCHLD,也不会中断父级中的任何类似wait 的调用。仅从 ps(1) 的角度来看,该过程或多或少“已失效”。
    • 好吧,从这个意义上说,所有线程都是由操作系统启动的。 pthread_exit(),根据定义,应该只退出当前线程,就像从任何其他线程调用它时一样。因此,期望主线程的行为方式与进程中的任何其他线程一样是完全合理的。但当然不是。
    • 很明显,主线程与任何其他线程一样:它必须由pthread_create()和操作-system 可以将其终止视为特殊的。
    猜你喜欢
    • 2010-11-12
    • 1970-01-01
    • 2016-03-31
    • 1970-01-01
    • 1970-01-01
    • 2014-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多