构成程序有问题

Having issues with forking a process

本文关键字:有问题 程序      更新时间:2023-10-16

所以我正在为我的一类写一个Unix shell,如果论点具有'&在它的末尾,我需要父进程调用wait();。

我的问题是,该程序应接受输入,直到我输入退出为止,因此所有内容都在" while"循环中。事情运行完美,直到我用"&"调用命令在它的末尾,然后我可以看到父过程结束了,然后孩子结束,但是我没有正常提示接受" osh>"的输入。

因此,当我运行一个简单命令时,这基本上是我的正常输出:

osh> ls -l
child:0
a.out  main  main.cpp  main.cpp~
parent: 8695 

,但是当我使用'&'运行命令时最后,这发生了:

osh> ls -l &
parent: 27082
osh> child:0
total 44
-rwxr-xr-x 1 myuser users 10368 Mar  1 14:46 a.out
-rwxr-xr-x 1 myuser users 23368 Mar  1 14:00 main
-rw-r--r-- 1 myuser users  1658 Mar  1 14:46 main.cpp
-rw-r--r-- 1 myuser users  1676 Mar  1 14:45 main.cpp~
<cursor is here accepting commands, but no osh> prompt>

如果有人发表任何评论或建议,将不胜感激。我觉得这只是一个小错误,但是我已经多次跑了一次调试器,找不到任何东西。我只是没有太多的经验。这是要查看的完整代码:

#include <stdio.h>
#include <unistd.h>
#include <iostream>
#include <string.h>
#include <string>
#include <cstring>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdlib.h>
#define MAX_LINE 80 //the maximum length command
using namespace std;
int main()
{
  char* args[MAX_LINE/2 + 1]; //command line arguments
  char str[41]; //intitialize string for input
  int should_run = 1; //flag to determine when to exit program
  bool status; //status of whether or not an ampersand is in the passed argument
  while (should_run) {
    int index = 0;
    cout << "osh> ";
    fflush(stdout);
    cin.getline(str, 41);
    args[index] = strtok(str, " ");
    while (args[index] != NULL) {
      index++;
      args[index] = strtok(NULL, " ");
    }
    if (strcmp (args[0], "exit") == 0) //in input is "exit", exit the while loop
      break;
    if (*args[index - 1] == '&') //check whether to run processes concurrently
      status = true;
    args[index - 1] = NULL; //remove & to make sure arguments are valid
    // (1) fork a child process using fork()
    pid_t pid = fork();
    if (pid < 0) { //error handling
      perror("Fork Failed.");
      break;
      }
    // (2) the child process will invoke execvp()
    if (pid == 0) {
      //child process
      cout << "child:" << pid << endl;
      if ( execvp (args[0], args) == -1 ) {
        perror ("exec");
      }
    }
    // (3) if command didn't included &, parent will invoke wait()
    //parent process
    if (pid > 0) {
        // parent process
       if (!status) {
         wait(0);
         }
       cout << "parent: " << pid << endl;
    }
  }
  return 0;
}

编辑:还意识到,在我发布的第二个输出上,它显示了" osh>"父程进程后的第二次,不确定如何描述该错误。

不,您已经在命令提示符:

osh> child:0
total 44

那是您的命令,提示,osh>提示。

您的问题是,您的计算机正是在做您要做的事情,而不是您想要的。您的代码(当时我会遇到一个无关的主要错误)说不要等到孩子的过程完成,然后继续进行&

这就是发生的事情。子过程开始了,您的父过程立即发出了下一个osh>提示。而且,它做得如此之快,在孩子过程甚至更改以产生任何输出之前。因此,在osh>提示符之后,子过程的输出出现在您的终端上。由于您的父程流程已经产生了提示,因此现在正在等待您的下一个输入,并且没有理由不继续等待,在孩子过程终止并完成了其输出后。

回答了您提示发生了什么问题。您没有解释您的期望发生的事情,因此对此无话可说。但是,如果您想再次重新发行提示,则在儿童过程终止之后,可以通过正确处理SIGCHLD信号来做到这一点。有关更多信息,请参见您的C 书。

至于您无关的错误,实际上是两个错误:

if (*args[index - 1] == '&')
  status = true;
args[index - 1] = NULL; //re

第一个错误:任何以'&'开头的东西,而不仅仅是"&amp;"本身将触发后台作业行为。

第二个错误:如果未输入'&',则此代码仍将删除输入的最后一个单词。这就是为什么当您输入命令ls -l时,您最终从第一个命令执行ls并从第一个命令中获取结果输出。