C 僵尸进程

C 僵尸进程,c,unix,process,posix,systems-programming,C,Unix,Process,Posix,Systems Programming,我想问一些关于僵尸进程的问题 僵尸流程概念的好处是什么 知道内核为僵尸进程保留(PID、终止状态、资源使用信息) “资源使用信息”是什么意思 zombie的PPID()=1,它仍然是zombie(init由于默认情况下等待(),所以会收获zombie) 任何人都可以编写一些C代码来制作僵尸吗?它的父级是Init 僵尸会拒绝释放一些内存锁吗 提前感谢僵尸进程纯粹是一个pid和退出状态值。无法释放pid,因为资源(pid)“属于”父级。如果它被释放,另一个进程可能会被分配相同的pid,然后父进程

我想问一些关于僵尸进程的问题

  • 僵尸流程概念的好处是什么
  • 知道内核为僵尸进程保留(PID、终止状态、资源使用信息)
    “资源使用信息”是什么意思
  • zombie的PPID()=1,它仍然是zombie(init由于默认情况下等待(),所以会收获zombie)
    任何人都可以编写一些C代码来制作僵尸吗?它的父级是Init
  • 僵尸会拒绝释放一些内存锁吗

提前感谢

僵尸进程纯粹是一个pid和退出状态值。无法释放pid,因为资源(pid)“属于”父级。如果它被释放,另一个进程可能会被分配相同的pid,然后父进程可能会向一个不相关的进程发送信号;即使家长首先等待确定孩子是否已经退出,也无法避免竞争条件。

--僵尸程序概念的好处是什么

僵尸进程只是一个pid、一个退出状态和一些记帐信息,直到父进程使用
wait
系列系统调用之一来获取其最终状态为止。在父进程调用
wait
之前,子进程的进程ID必须保持标记为已使用,以便不能为其分配其他进程。如果另一个进程被分配了一个循环的pid,那么很难区分它与以前具有相同pid的进程之间的区别。父级调用
wait
并返回最终退出状态后,可以假设没有人会再次在该pid上查找子级,因此现在可以重用该pid。 (我认为在Linux上,如果父级将SIGCHLD保留为SIG_-IGN,内核将不会保留僵尸,但将SIGCHLD的处置重新注册为SIG_-IGN不会产生相同的效果)

--知道内核为僵尸进程保留(PID、终止状态、资源使用信息)“资源使用信息”是什么意思

其中一些信息是运行程序的方式:

time my_program
我将报告。这些值通常在SIGCHLD的siginfo结构中报告(这并不完全是对
wait
)的调用,但也可以通过调用systme调用的
waitid
形式获得(在某些系统上)。查看
mansigaction
了解有关此结构的信息

--zombie的PPID()=1,但它仍然是zombie(init会收获zombie,因为默认情况下它会等待())

ppid=1的僵尸不应该在僵尸中呆很长时间,因为init应该很快收获它。一个进程在死后不久(通过
退出
或通过一个杀死它的未受伤害的信号)的某一点将保持僵尸状态,直到其父进程调用
等待
并获得它的最终状态。这意味着,即使init除了反复调用init之外什么都不做,也可能会有一小段时间进程会显示为僵尸。如果进程在很长时间(秒)内显示为init(0=ppid)的子进程,那么可能是出了问题

--任何人都可以编写一些C代码来制作僵尸吗?它的父级是Init

这还不清楚,但我想你想要:

pid_t f = fork();
if (f > 0) {
    exit(0); // this is the parent dying, so the child will be an orphan
             // and get adopted by init
} else if (f == 0) {
    sleep(100); // This is the child doing something that takes enough time for
                // its parent to commit suicide (exit(0)) and then for you to
                // observe that it has now been adopted by init
    exit(0);    // And now it dies as well, so init should reap its status, but
                // it may be a zombie for a short amount of time first.
} else /* error condition would be handled here */
--僵尸会拒绝释放一些内存锁吗


僵尸什么都抓不住。它们会丢失所有的内存页、打开的文件句柄等等。几乎所有操作系统能够弄清楚如何释放的东西都应该被释放。如果不这样做,那将是一个bug,但请记住,操作系统必须知道它是应该被释放的。在用户空间中创建资源非常容易,当操作系统不知道应该释放的程序死亡时,这些资源应该被释放。

如果您有兴趣在正在运行的进程列表中看到僵尸进程,请使用以下方法:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main(void)
{
    pid_t p = fork();   // creates child process and stores the returned PID

    if (p != 0)         // executed by parent process
    {   sleep(1);       /* the child process terminates while the parent process sleeps,
                           the child then becomes a zombie process because the returned status
                           of the terminated child process isn't checked via a wait() */

        system("ps -eo pid,ppid,stat,cmd");  // prints a list of processes in your terminal

    }
    else        // executed by child process
    {
        exit(0);        // the child process terminates immediately
    }

    return 0;
}
#包括
#包括
#包括
内部主(空)
{
pid_t p=fork();//创建子进程并存储返回的pid
if(p!=0)//由父进程执行
{sleep(1);/*子进程在父进程睡眠时终止,
然后,由于返回的状态
未通过wait()检查终止的子进程的*/
系统(“ps-eo pid,ppid,stat,cmd”);//打印终端中的进程列表
}
else//由子进程执行
{
退出(0);//子进程立即终止
}
返回0;
}
您可以通过列表中的Z+标识僵尸进程:


注意:如果使用windows,则必须修改代码。

僵尸进程是指已停止运行但其进程表项仍然存在的进程,因为父进程尚未通过等待系统调用检索到它。从技术上讲,每一个终止的进程在很短的时间内都是一个僵尸,但它们可以存活更长的时间


当父进程在子进程完成后不调用wait syscall时,会出现寿命更长的僵尸进程。出现这种情况的一种情况是,父进程写得不好,只是省略了等待调用,或者父进程在子进程之前就死了,而新的父进程没有对其调用等待。当进程的父进程先于子进程死亡时,操作系统将子进程分配给“init”进程或PID 1。i、 e.init进程“采用”子进程并成为其父进程。这意味着,现在当子进程退出时,新的父进程(init)必须调用wait以获取其退出代码,否则其进程表条目将永远保留,并成为超级用户上的僵尸。com@PaulR我不这么认为,这些都在系统编程之下……我想我遗漏了一些东西。您正在使用的僵尸进程的定义是什么?已退出但其父进程尚未获得退出通知的子进程