V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
b00tyhunt3r
V2EX  ›  程序员

在子进程中执行 execve 之后子进程自身处于什么状态?

  •  
  •   b00tyhunt3r · 2019-09-05 21:18:52 +08:00 · 2481 次点击
    这是一个创建于 1666 天前的主题,其中的信息可能已经有所发展或是发生改变。
    发射一个 SIGCHLD 信号给老父亲然后嗷一声就终止了?求解!
    sfqtsh
        1
    sfqtsh  
       2019-09-05 21:30:36 +08:00 via Android
    Zombie?
    b00tyhunt3r
        2
    b00tyhunt3r  
    OP
       2019-09-05 21:43:22 +08:00
    @sfqtsh
    如果是僵尸还好说,然而自己做了个实验,被吓呆了

    int main()
    {
    int pid;
    printf("father:%d\n",getpid());
    pid = fork();
    if (pid ==0)
    {
    execve("bin/date",NULL,NULL);
    printf("child:%d\n",getpid());
    printf("father:%d\n",getppid());
    }
    }

    运行结果:
    father:38215
    child:38216
    father:1

    儿子把父亲杀了??????
    forcecharlie
        3
    forcecharlie  
       2019-09-05 21:57:45 +08:00 via iPhone
    @b00tyhunt3r pid!=0 自己退出了 然后 child 被 init 收养了
    forcecharlie
        4
    forcecharlie  
       2019-09-05 21:59:11 +08:00 via iPhone
    @b00tyhunt3r 而且你的 execve 应该是失败了 成功没有返回
    b00tyhunt3r
        5
    b00tyhunt3r  
    OP
       2019-09-05 22:01:32 +08:00
    @forcecharlie
    子进程执行 execve 以后, 父进程为什么会终止?该终止的不是子进程吗

    不知道 getpid 能否得到僵尸进程的 pid
    raptium
        6
    raptium  
       2019-09-05 22:04:57 +08:00 via iPhone
    execve 后面的代码不会执行了吧?怎么还能 print 出来的
    b00tyhunt3r
        7
    b00tyhunt3r  
    OP
       2019-09-05 22:11:01 +08:00
    信号果然没人说得清吗。。。有没有大牛来救场的
    ysc3839
        8
    ysc3839  
       2019-09-05 22:48:58 +08:00
    @b00tyhunt3r 你写错了吧?确定不是 "/bin/date" 而是 "bin/date"?
    fairytale
        9
    fairytale  
       2019-09-05 22:55:19 +08:00 via iPhone
    execve 不是用新命令替换自身内存空间么?后面下一行的代码不会执行了。新命令想终止就自然终止呗。
    记得 execve 之前先 fork,否则就是自身被替换。2 楼的代码没毛病,但是建议换个执行时间长的命令,date 执行时间太短了。
    ooxxcc
        10
    ooxxcc  
       2019-09-05 22:58:32 +08:00
    @b00tyhunt3r 父进程的 pid 变量不等于 0,后面没代码了,难道不就退出了……
    fairytale
        11
    fairytale  
       2019-09-05 23:01:00 +08:00 via iPhone
    类似 date 这种秒退,当然发送 SIGCHLD 了啊。换个 sleep10,就 10 秒后 SIGCHLD
    fairytale
        12
    fairytale  
       2019-09-05 23:03:44 +08:00 via iPhone
    10 喽说的对,里面两个 print 放到引号外面,再加个 sleep。
    fairytale
        13
    fairytale  
       2019-09-05 23:09:36 +08:00 via iPhone
    int main()
    {
    int pid;
    char * argv[ ]={"/bin/sleep","10",(char *)0};
    printf("father:%d\n",getpid());
    pid = fork();
    if (pid ==0)
    {
    execve("/bin/sleep",argv,NULL);
    printf("execve failed\n");
    }
    sleep(1);
    printf("child:%d\n",getpid());
    printf("father:%d\n",getppid());
    sleep(10);
    }
    lxy42
        14
    lxy42  
       2019-09-05 23:57:58 +08:00 via Android
    子进程 execve 后,进城地址空间被新程序覆盖了,你后面两个 printf 是不会执行的,你测试发现执行了是因为你调用 execve 的方式错了,导致 execve 执行失败。
    x1314aq
        15
    x1314aq  
       2019-09-06 08:18:57 +08:00 via iPhone
    @b00tyhunt3r 父进程执行完 fork()后就正常退出了,return 0 正常退出了;子进程被 init 收养,然后子进程的 execve 失败,pintf 出来的 ppid=1 ;你要想像正常的多进程程序那样,得加一个 else 分支,在 else 分支里,父进程调用 wait(),等待子进程结束
    lolizeppelin
        16
    lolizeppelin  
       2019-09-06 10:09:53 +08:00
    你 fork 以后啥都没 进程不退出还能干啥 233
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5865 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 02:00 · PVG 10:00 · LAX 19:00 · JFK 22:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.