【问题标题】:Program will not exit after calling exit()调用exit()后程序不会退出
【发布时间】:2019-09-20 07:34:27
【问题描述】:

我有以下代码。有人可以向我解释为什么键入“退出”时程序不会退出。该程序可以运行,如果您在它开始时键入 exit,它就可以运行。输入 a 后程序不会退出,例如输入 a 然后 b 然后 c 您必须输入 exit 4 次才能退出程序

#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <cstdlib>
#include <stdlib.h>
#include <stdio.h>
#include <wait.h>

using namespace std;

//*********************************************************
//
// Extern Declarations
//
//*********************************************************
using namespace std;
extern "C" {
    extern char **gettoks();
}

//*********************************************************
//
// Main Function
//
//*********************************************************
int main(int argc, char *argv[])
{
    // local variables
    int ii;
    char **toks;
    int retval;

    pid_t pid;
    int status;
    char folder[80];
    retval = 0;

    cout << "Welcome to Island Shell" << endl;
    while (true)
    {
        printf("Island Shell$ ");
        toks = gettoks();
        if (toks[0] != NULL)
        {
            if( !strcmp( toks[0], "exit" ))
            {
                exit(0);
            }
            pid = fork();
            if (pid == 0)
            {
                strcpy(folder,"/bin/");
                strcat(folder,toks[0]);
                execv(folder,toks);
            }
            else
            {
                wait(&status);
            }
        }
    }
    return (retval);
}

【问题讨论】:

  • 你确定它到达了那个代码吗?尝试添加一条跟踪线,看看它是否完全到达它。
  • @solarflare 是的,我找到了代码。例如,如果我输入 1,然后输入 2,然后输入 3,会发生什么情况,我将不得不输入 exit 4 次。

标签: c++


【解决方案1】:

你没有显示char **gettoks(),所以很难确定,但这是我的猜测,假设函数返回你的键盘输入。

当你输入 1 时,你会得到tok[0]==1,然后fork() 创建同一进程的第二个副本,并在它结束时等待。目的是通过调用execv 将这个新进程替换为另一个程序,但是execv 没有找到名为1 的程序并且失败了,因此您最终得到了同一进程的2 个副本。

通过输入 2 和 3 重复此操作后,您最终会得到 4 个进程副本,彼此等待。退出所有 4 个进程需要 4 个exit 命令。

【讨论】:

  • 我正在阅读我的操作系统书籍中的系统调用,但似乎找不到答案。我现在知道是什么问题了,谢谢。例如,如果找不到名为 1 的程序,似乎无法找到是否有终止进程的方法。
  • 只需在execv() 之后添加exit(1) 调用。如果execv() 成功,程序将无法访问它。