【问题标题】:Fork and exec multiple processes simultaneously同时分叉和执行多个进程
【发布时间】:2017-01-28 22:33:49
【问题描述】:

我正在研究自制的外壳(非常简单的外壳)。我决定采用使用 execvp 的路线,因为我的路径对于我的 shell 来说是不可更改的元素。我遇到了一个关于如何一次分叉和执行多个进程的逻辑的问题。

我的程序应该使用这样的命令:

ls ; echo hello ; cat shell.c

每个“;”表示我们希望同时运行这些进程。因此,在我们的终端输出中,我们应该同时使用这些命令。

为了详细说明,我想解释一下我的程序是如何工作的:

A. Intake full command line into char array with a grab line function
B. Split the char array received from the last function by delimiters and place into an array of char arrays (pointer to pointer).
C. If one of the elements in our array of char arrays is ";" we can assume that multi commands are necessary. This is where I have trouble.

我已经确切地知道我需要分叉多少进程等等,但我似乎无法解决如何将所有这些函数以及它们的参数一次传递给 execvp 函数。我应该使用临时数组吗?我知道这不应该这么复杂,但由于某种原因我无法弄清楚。我在下面提交了我的启动函数,它接收一个字符数组数组并根据我的“multiCommand”变量相应地执行,该变量是在需要多命令时设置的(通过我的分割线函数)

int launch(char **args){

    pid_t pid;
    int status;
    int i = 0;

    if(strcmp(args[0], "quit") == 0){
        exit(EXIT_SUCCESS);
    }

    if(strcmp(args[0], ";") != 0){
        printf("Essential Command Found : %s\n", args[0]);
        numFork++;
    }


    if(multiCommand == 1){
        //Handle Multicommands here
        printf("Multi Commands Handling Here\n");

        for(; i < elements - 1; i++){
            if(strcmp(args[i], ";") == 0){
                if((i + 1) < elements){
                    printf("Essential Command Found : %s\n", args[i + 1]);
                    numFork++;
                }
            }
        }

        //This is where I need to figure out what to do

        printf("Fork: %d times\n", numFork);


    }else if (multiCommand == 0){
        pid = fork();
        if(pid == 0){
            execvp(args[0], args);

        }else{
            wait(&status);
        }
    }

    multiCommand = 0;   
    elements = 0;

    return 1;
}

【问题讨论】:

  • 旁注:在标准 shell 中,; 通常表示仅在另一端结束后运行一个,&amp; 表示在后台运行,这会导致下一个运行而无需等待前一个完成.
  • 您必须为要运行的每个进程分叉一次。相应的孩子将知道要执行哪个命令(您必须确保这一点)。 execvp() 系统调用只会运行一个命令,而不是很多(但一个命令可能是一个 shell,然后继续运行许多命令)。

标签: c linux shell fork exec


【解决方案1】:

一般的想法是对不同的命令进行 for 循环,然后对每个命令进行 fork。

例如

for(int i = 0; i < commandCount; i++) {
    int pid = fork();
    if(pid == 0) { //this is the child (don't forget to check for errors and what-not)
        execCommand(all, of, the, info, needed);
    }
}

您可以使用strtok() 轻松获取不同的命令。
这是一个例子:

#include <string.h>
#include <stdio.h>
int main() {
    char input[] = "abc;def;ghi";
    char *token = strtok(input, ";");
    while(token != NULL) {
        printf("%s\n", token);
        token = strtok(NULL, ";");
    }
    return 0;
}

输出:

abc
def
ghi

最终的函数将如下所示:

char *token = strtok(input, ";");
while(token != NULL) {
    int pid = fork();
    if(pid == 0) {
        //token is one command
        //parse the different parts here
        execCommand(args, to, exec);
    }
    token = strtok(NULL, ";");
}

【讨论】:

  • 谢谢,我想对我来说最困难的部分是将命令作为“execvp”的第二个参数传递到下一个分号。我似乎无法弄清楚那部分。
  • 如果你让它适用于单个命令,你可以将输入分解为一个 char 数组数组,并以与单个命令相同的方式传递它们。
猜你喜欢
  • 1970-01-01
  • 2015-01-26
  • 2023-04-04
  • 2017-02-06
  • 1970-01-01
  • 2021-05-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多