C 当我没有在父进程中等待子进程时,如何终止程序?

C 当我没有在父进程中等待子进程时,如何终止程序?,c,fork,wait,kill,execvp,C,Fork,Wait,Kill,Execvp,我正在尝试制作一个模仿Linux shell的程序 它以两种模式运行 (1) 交互模式(无参数) 等待子进程。一次执行一个命令 (2) 批处理模式(给定文件) 不要等待。尝试并行执行这些命令 我的代码相当长,所以我决定制作一个示例程序来解决(关注)我所面临的问题 #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include &

我正在尝试制作一个模仿Linux shell的程序

它以两种模式运行

(1) 交互模式(无参数)

等待子进程。一次执行一个命令

(2) 批处理模式(给定文件)

不要等待。尝试并行执行这些命令

我的代码相当长,所以我决定制作一个示例程序来解决(关注)我所面临的问题

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

struct commands
{
    char *cmd[2];
};

int main(int argc, char *argv[])
{
    printf("A program made to understand execvp\n");

    commands threeCommands[3];

    pid_t process;
    int child_status;

    threeCommands[0].cmd[0] = "date";
    threeCommands[0].cmd[1] =  NULL;

    threeCommands[1].cmd[0] = "pwd";
    threeCommands[1].cmd[1] =  NULL;

    threeCommands[2].cmd[0] = "cal";
    threeCommands[2].cmd[1] =  NULL;

    for(int i = 0;i <3;i++)
    {
        process = fork();

        if(process == 0)
        {
            execvp(threeCommands[i].cmd[0],threeCommands[i].cmd);
        }
        else
        {
             //wait(&child_status);
        }
    }

    return 0;
}
#包括
#包括
#包括
#包括
#包括
结构命令
{
char*cmd[2];
};
int main(int argc,char*argv[])
{
printf(“为理解execvp而制作的程序”);
命令三个命令[3];
pid_t过程;
国际儿童基金会地位;
三个命令[0].cmd[0]=“日期”;
三个命令[0].cmd[1]=NULL;
三个命令[1].cmd[0]=“pwd”;
三个命令[1].cmd[1]=NULL;
三个命令[2].cmd[0]=“cal”;
三个命令[2].cmd[1]=NULL;

对于(int i=0;i您必须调用
wait
,子进程才能干净地终止。您不必立即调用
wait
,但必须在程序结束之前调用
wait
,否则您就有僵尸子进程。这对我来说很有效,并且仍然并行运行所有程序:

#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

struct commands
{
    char *cmd[2];
};

int main(int argc, char *argv[])
{
    printf("A program made to understand execvp\n");

    struct commands threeCommands[3];

    pid_t process;
    int child_status;

    threeCommands[0].cmd[0] = "date";
    threeCommands[0].cmd[1] =  NULL;

    threeCommands[1].cmd[0] = "pwd";
    threeCommands[1].cmd[1] =  NULL;

    threeCommands[2].cmd[0] = "cal";
    threeCommands[2].cmd[1] =  NULL;

    for(int i = 0;i <3;i++)
    {
        process = fork();

        if(process == 0)
        {
            execvp(threeCommands[i].cmd[0],threeCommands[i].cmd);
        }
    }

    for(int i = 0;i <3;i++)
    {
        wait(&child_status);
    }

    return 0;
}
输出后只需按Enter键

如果父进程先于子进程退出,则外壳程序将在父进程退出后打印提示,然后子进程打印其输出,但外壳程序不会打印新提示。请查看输出末尾上方的几行,以查看父进程退出后的提示

例如,在修改代码以添加
睡眠(1)
之后,在调用
execvp
(强制子进程延迟)之前,我在系统上获得以下输出:

[~/tmp]$ ./a.out A program made to understand execvp [~/tmp]$ tis 9 feb 2016 18:54:06 CET /home/XXXX/tmp Februari 2016 sö må ti on to fr lö 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 [~/tmp]$./a.out 为理解execvp而制作的程序 [~/tmp]$tis 2016年2月9日18:54:06 CET /主页/XXXX/tmp 2016年2月 sömåti关于löf r 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
正如您所看到的,提示符是在
日期
命令运行之前打印的(在
日期
输出之前的
[~/tmp]$
)。按Enter键将返回提示符。

实际上不必调用
等待
来获取子进程,即使这样做是“礼貌的”。如果子进程成为孤立进程(当其父进程在不等待子进程退出的情况下退出时)初始化进程(pid 1)将作为父进程接管。僵尸进程是一个已退出但尚未收获的进程是(即父进程未调用
等待
).那太棒了,但我该如何在代码中输入enter键?所以我不需要这样做manually@Pro不能,因为父进程不再存在。:)这是从shell启动的程序中的子进程的已知“问题”。 [~/tmp]$ ./a.out A program made to understand execvp [~/tmp]$ tis 9 feb 2016 18:54:06 CET /home/XXXX/tmp Februari 2016 sö må ti on to fr lö 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29