关于子进程杀死父进程的问题

时间:2021-08-15 21:14:40
现在我需要在子进程中杀死父进程,但是子进程仍然要运行,我试了两种方法,但是都没有达到预期的效果,结果是父进程和子进程,都被杀死了。请高手指点问题在哪里,或者有什么其他的方法,谢谢。
方法1:
        因为有文章介绍说,system调用,本身就创建了一个子进程。于是我写了一个脚本,将父进程的进程号做参数,传进去,脚本这样写的
        sleep  20
        kill $1
        ........
        getty 115200      tty0      
        ......
      在运行脚本后,我ps,看到系统中有脚本的进程,sleep 20 就是为了看看是否有脚本的进程。等大概20秒后,执行kill之后,发现父进程杀死了,但是脚本的进程也被杀死了。这是为什么?

方法2:
         方法一出了问题,我就认为是不是要自己调用fork()来创建子进程,于是我就写下面的函数

          int main(viod)
          {
                 int fd;
                 ......
                
                 fd=fork();
                  if(fd==0)
                  {
                             调用system()杀死父进程。
                             while(1);
                  }
          }

本来我没有加while(1),,因为我在看到杀死父进程后,自子进程也被杀死了,我觉得可能是子进程执行完了,退出了,所以我加一个死循环,子进程永远不会退出,但是结果,子进程仍然是被杀死了。
我看过说killall会杀死父进程和他的所有子进程,所以我特意用kill,但是为什么还是不行,高手指点阿。






9 个解决方案

#1


你的system执行的命令是怎么样的?
我用你的第二种方案写了一个程序,如下,
int main(argn,argc,argv)
int argn;
char *argc[],*argv[];
{
        pid_t pid,ppid;

        ppid = getpid();
        if ((pid = fork()) < 0){
                return -1;
        }
        else if (pid == 0){
                int i = 0;
                char cmd[256];
                sprintf(cmd,"kill -9 %d",ppid);
                i = system(cmd);
                while(1){
                        printf("kill result is %d\n",i);
                }
                return 0;
        }
        else {
                while(1)
                ;
        }
}
运行之后一直打印kill result is 0

#2


试试以下的程序:
mymtom@freebsd:src/csdn/unix/kill$ cat child.sh
#!/bin/sh
sleep 30
kill $1
echo $?
sleep 10

mymtom@freebsd:src/csdn/unix/kill$ cat parent.c
#include <sys/types.h>
#include <unistd.h>

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

int main(void)
{
        pid_t pid;
        char s[64 + 1];

        pid = getpid();
        sprintf(s, "./child.sh %d", pid);
        system(s);
        for (;;)
        {
                sleep(60);
        }
}

#3


sleep 10
kill $1
sleep 5
getty 115200 tty0
export LD_LIBRARY_PATH=/usr/gsl/lib
cd /tmp
./MoPlayer &

这个脚本,先kill 主进程,然后(getty 115200 tty0)启动控制台,这个时候板子上的控制台就会出来,脚本就停留在这里,当在目标板子上的控制台(exit—)退出的时候,就会继续执行脚本,运行下面的启动程序。
当然,这是我的目的,但是我试了不行。

我想问一下,当你kill掉主程序后,你ps,有看到子进程在运行吗?

#4


有啊!
mymtom@freebsd:src/csdn/unix/kill$ ./parent &
[1] 40275
mymtom@freebsd:src/csdn/unix/kill$ date
Thu Nov  8 14:58:01 CST 2007
mymtom@freebsd:src/csdn/unix/kill$ ps
  PID  TT  STAT      TIME COMMAND
39278  p4  Is     0:00.01 -bash (bash)
39446  p4  S      0:00.03 ksh
40275  p4  S      0:00.00 ./parent
40276  p4  S      0:00.00 sh -c ./child.sh 40275
40277  p4  S      0:00.00 /bin/sh ./child.sh 40275
40278  p4  S      0:00.00 sleep 30
40280  p4  R+     0:00.00 ps
mymtom@freebsd:src/csdn/unix/kill$ date
Thu Nov  8 14:58:14 CST 2007
mymtom@freebsd:src/csdn/unix/kill$ ps
  PID  TT  STAT      TIME COMMAND
39278  p4  Is     0:00.01 -bash (bash)
39446  p4  S      0:00.04 ksh
40275  p4  S      0:00.00 ./parent
40276  p4  S      0:00.00 sh -c ./child.sh 40275
40277  p4  S      0:00.00 /bin/sh ./child.sh 40275
40278  p4  S      0:00.00 sleep 30
40285  p4  R+     0:00.00 ps
mymtom@freebsd:src/csdn/unix/kill$ 0
date
Thu Nov  8 14:58:32 CST 2007
[1] + Terminated           ./parent 
mymtom@freebsd:src/csdn/unix/kill$ ps
  PID  TT  STAT      TIME COMMAND
39278  p4  Is     0:00.01 -bash (bash)
39446  p4  S      0:00.04 ksh
40276  p4  I      0:00.00 sh -c ./child.sh 40275
40277  p4  S      0:00.00 /bin/sh ./child.sh 40275
40287  p4  S      0:00.00 sleep 10
40289  p4  R+     0:00.00 ps
mymtom@freebsd:src/csdn/unix/kill$ date
Thu Nov  8 14:58:42 CST 2007
mymtom@freebsd:src/csdn/unix/kill$ ps
  PID  TT  STAT      TIME COMMAND
39278  p4  Is     0:00.01 -bash (bash)
39446  p4  S      0:00.04 ksh
40291  p4  R+     0:00.00 ps
mymtom@freebsd:src/csdn/unix/kill$ 

#5


哦,我好像知道什么问题了。我最初以为杀掉父进程,让子进程运行脚本,可以达到目的,现在发现不行。
一定要用将进程完全杀掉。
有办法在一个脚本里面,调用killall杀掉进程,但是脚本仍然运行吗?
我的任务是要启动控制台,本来目标板子上在运行一个程序MoPlayer,接着可以按键出来菜单,菜单里面有一个选择
是启动控制台。控制台已经做好了,通过运行shell命令,可以启动,但是必须要完全杀掉MoPlayer,才能看到
控制台界面。
我的脚本是这样写的。

killall MoPlayer
sleep 5
#input console drive
/usr/.boot/fbcon.sh
sleep 5
getty 115200 tty0
export LD_LIBRARY_PATH=/usr/gsl/lib
cd /tmp
./MoPlayer &


现在的问题是执行killall MoPlayer这个后,这个脚本也被杀死了,不会执行后面的语句了。但是又必须杀掉所有进程,才能启动控制台,真是苦恼。

#6


在板子上运行啊?
这个没有弄过,不懂,帮顶!

#7


为什么“必须杀掉所有进程,才能启动控制台”?那就让init去启动控制台了。

#8


谢谢大家,这个问题我已经解决了,既然是必须要杀死所有进程,才能启动控制台,原因是这个控制台就是这样做的
它需要的界面,不能被其它的程序占用。
那么,我就最初运行脚本,在脚本里面运行我的应用程序,当我的程序退出,或者某个时候,我可以在脚本里面杀掉
我的应用程序,接着启动控制台,上面的矛盾就解决了。谢谢大家的出谋划策。

#9


引用 8 楼 szduweibing 的回复:
谢谢大家,这个问题我已经解决了,既然是必须要杀死所有进程,才能启动控制台,原因是这个控制台就是这样做的
它需要的界面,不能被其它的程序占用。
那么,我就最初运行脚本,在脚本里面运行我的应用程序,当我的程序退出,或者某个时候,我可以在脚本里面杀掉
我的应用程序,接着启动控制台,上面的矛盾就解决了。谢谢大家的出谋划策。


楼主怎么解决的呀 。。。 ?? 求方法,我也碰到类似的问题 ,纠结点在于不能并行运行,
我要子进程结束父进程(子进程循环查询 父进程运行到某个结果时,kill 父进程) ,所以子进程是放到后台(因为父进程运行是没法自己停止的,要子进程去kill它,所以父进程不运行完,子进程是没法运行,所以我只能把子进程放到后台 ,让其和父进程并行运行 )

#1


你的system执行的命令是怎么样的?
我用你的第二种方案写了一个程序,如下,
int main(argn,argc,argv)
int argn;
char *argc[],*argv[];
{
        pid_t pid,ppid;

        ppid = getpid();
        if ((pid = fork()) < 0){
                return -1;
        }
        else if (pid == 0){
                int i = 0;
                char cmd[256];
                sprintf(cmd,"kill -9 %d",ppid);
                i = system(cmd);
                while(1){
                        printf("kill result is %d\n",i);
                }
                return 0;
        }
        else {
                while(1)
                ;
        }
}
运行之后一直打印kill result is 0

#2


试试以下的程序:
mymtom@freebsd:src/csdn/unix/kill$ cat child.sh
#!/bin/sh
sleep 30
kill $1
echo $?
sleep 10

mymtom@freebsd:src/csdn/unix/kill$ cat parent.c
#include <sys/types.h>
#include <unistd.h>

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

int main(void)
{
        pid_t pid;
        char s[64 + 1];

        pid = getpid();
        sprintf(s, "./child.sh %d", pid);
        system(s);
        for (;;)
        {
                sleep(60);
        }
}

#3


sleep 10
kill $1
sleep 5
getty 115200 tty0
export LD_LIBRARY_PATH=/usr/gsl/lib
cd /tmp
./MoPlayer &

这个脚本,先kill 主进程,然后(getty 115200 tty0)启动控制台,这个时候板子上的控制台就会出来,脚本就停留在这里,当在目标板子上的控制台(exit—)退出的时候,就会继续执行脚本,运行下面的启动程序。
当然,这是我的目的,但是我试了不行。

我想问一下,当你kill掉主程序后,你ps,有看到子进程在运行吗?

#4


有啊!
mymtom@freebsd:src/csdn/unix/kill$ ./parent &
[1] 40275
mymtom@freebsd:src/csdn/unix/kill$ date
Thu Nov  8 14:58:01 CST 2007
mymtom@freebsd:src/csdn/unix/kill$ ps
  PID  TT  STAT      TIME COMMAND
39278  p4  Is     0:00.01 -bash (bash)
39446  p4  S      0:00.03 ksh
40275  p4  S      0:00.00 ./parent
40276  p4  S      0:00.00 sh -c ./child.sh 40275
40277  p4  S      0:00.00 /bin/sh ./child.sh 40275
40278  p4  S      0:00.00 sleep 30
40280  p4  R+     0:00.00 ps
mymtom@freebsd:src/csdn/unix/kill$ date
Thu Nov  8 14:58:14 CST 2007
mymtom@freebsd:src/csdn/unix/kill$ ps
  PID  TT  STAT      TIME COMMAND
39278  p4  Is     0:00.01 -bash (bash)
39446  p4  S      0:00.04 ksh
40275  p4  S      0:00.00 ./parent
40276  p4  S      0:00.00 sh -c ./child.sh 40275
40277  p4  S      0:00.00 /bin/sh ./child.sh 40275
40278  p4  S      0:00.00 sleep 30
40285  p4  R+     0:00.00 ps
mymtom@freebsd:src/csdn/unix/kill$ 0
date
Thu Nov  8 14:58:32 CST 2007
[1] + Terminated           ./parent 
mymtom@freebsd:src/csdn/unix/kill$ ps
  PID  TT  STAT      TIME COMMAND
39278  p4  Is     0:00.01 -bash (bash)
39446  p4  S      0:00.04 ksh
40276  p4  I      0:00.00 sh -c ./child.sh 40275
40277  p4  S      0:00.00 /bin/sh ./child.sh 40275
40287  p4  S      0:00.00 sleep 10
40289  p4  R+     0:00.00 ps
mymtom@freebsd:src/csdn/unix/kill$ date
Thu Nov  8 14:58:42 CST 2007
mymtom@freebsd:src/csdn/unix/kill$ ps
  PID  TT  STAT      TIME COMMAND
39278  p4  Is     0:00.01 -bash (bash)
39446  p4  S      0:00.04 ksh
40291  p4  R+     0:00.00 ps
mymtom@freebsd:src/csdn/unix/kill$ 

#5


哦,我好像知道什么问题了。我最初以为杀掉父进程,让子进程运行脚本,可以达到目的,现在发现不行。
一定要用将进程完全杀掉。
有办法在一个脚本里面,调用killall杀掉进程,但是脚本仍然运行吗?
我的任务是要启动控制台,本来目标板子上在运行一个程序MoPlayer,接着可以按键出来菜单,菜单里面有一个选择
是启动控制台。控制台已经做好了,通过运行shell命令,可以启动,但是必须要完全杀掉MoPlayer,才能看到
控制台界面。
我的脚本是这样写的。

killall MoPlayer
sleep 5
#input console drive
/usr/.boot/fbcon.sh
sleep 5
getty 115200 tty0
export LD_LIBRARY_PATH=/usr/gsl/lib
cd /tmp
./MoPlayer &


现在的问题是执行killall MoPlayer这个后,这个脚本也被杀死了,不会执行后面的语句了。但是又必须杀掉所有进程,才能启动控制台,真是苦恼。

#6


在板子上运行啊?
这个没有弄过,不懂,帮顶!

#7


为什么“必须杀掉所有进程,才能启动控制台”?那就让init去启动控制台了。

#8


谢谢大家,这个问题我已经解决了,既然是必须要杀死所有进程,才能启动控制台,原因是这个控制台就是这样做的
它需要的界面,不能被其它的程序占用。
那么,我就最初运行脚本,在脚本里面运行我的应用程序,当我的程序退出,或者某个时候,我可以在脚本里面杀掉
我的应用程序,接着启动控制台,上面的矛盾就解决了。谢谢大家的出谋划策。

#9


引用 8 楼 szduweibing 的回复:
谢谢大家,这个问题我已经解决了,既然是必须要杀死所有进程,才能启动控制台,原因是这个控制台就是这样做的
它需要的界面,不能被其它的程序占用。
那么,我就最初运行脚本,在脚本里面运行我的应用程序,当我的程序退出,或者某个时候,我可以在脚本里面杀掉
我的应用程序,接着启动控制台,上面的矛盾就解决了。谢谢大家的出谋划策。


楼主怎么解决的呀 。。。 ?? 求方法,我也碰到类似的问题 ,纠结点在于不能并行运行,
我要子进程结束父进程(子进程循环查询 父进程运行到某个结果时,kill 父进程) ,所以子进程是放到后台(因为父进程运行是没法自己停止的,要子进程去kill它,所以父进程不运行完,子进程是没法运行,所以我只能把子进程放到后台 ,让其和父进程并行运行 )