【问题标题】:What am I doing wrong to end this while loop我做错了什么来结束这个while循环
【发布时间】:2014-03-24 14:21:08
【问题描述】:

我正在使用“int flag = [0 or 1]”来确定我的循环是否应该回到 do{}。 这是我的代码

void shell() 
{
    int flag = 1;
    do
    {
        // Retrieve PID of the parent process. 
        pid_t shell_pid = getpid();

        // Print shell prompt. 
        printf("{%i}$ ", shell_pid);

        // Retrieve input from stdin.
        char* input = NULL;
        size_t input_size = 0;
        getline(&input, &input_size, stdin);
        char delim = ' ';
        char **argvp;
        int argc = makeargv(input, &delim, &argvp);

        // Remove \n from last arg
        char* lastarg = argvp[argc - 1];
        while(*lastarg && *lastarg != '\n')
            lastarg++;
        *lastarg = '\0';

        // Create a child process to handle user input. 
        pid_t pid = fork();

        // Parent process.  
        if (pid != 0) 
        {
            wait(NULL);
        } 
        else // Child process
        {
            int i;
            // Handle user input here!

            //got some debugging tools here
            printf("========DEBUG==========\n");
            printf("There are %i args\n", argc);
            for(i = 0; i < argc; i++)
            {
                printf("arg %i: \"%s\"\n", i, *(argvp + i));
            }
            printf("=====END DEBUG==========\n\n");
            printf("********OUTPUT*********\n");
            //handle "echo" here
            if((i = strcmp(argvp[0],"echo")) == 0)
            {
                echo(argc, argvp);
            }

            //handle "exit" or "quit" here
            if((i = strcmp(argvp[0],"exit")) == 0 || (i = strcmp(argvp[0],"quit")) == 0)
            {
                printf("got in the exit\n");
                flag = 0;
            }

        }
        printf("****END OUTPUT*********\n");
        // Free memory allocated by getline(). 
        free(input);
    }while(flag == 1);    
}

我的输入/输出看起来像这样:[输入前面是 $]

$ ./shelltest
{13158}$ try first string
========DEBUG==========
There are 3 args
arg 0: "try"
arg 1: "first"
arg 2: "string"
=====END DEBUG==========

********OUTPUT*********
****END OUTPUT*********
{13159}$ echo try another
========DEBUG==========
There are 3 args
arg 0: "echo"
arg 1: "try"
arg 2: "another"
=====END DEBUG==========

********OUTPUT*********
try another 
****END OUTPUT*********
{13160}$ quit 
========DEBUG==========
There are 1 args
arg 0: "quit"
=====END DEBUG==========

********OUTPUT*********
got in the exit
****END OUTPUT*********
****END OUTPUT*********
{13160}$

由于输出中显示了“进入出口”,因此立即将 flag 设置为 0。 循环是怎么继续的?

【问题讨论】:

  • 是什么让你说循环继续?
  • 因为我被重新提示输入“{13160}$”

标签: c loops flags do-while


【解决方案1】:

你正在使用fork(),父进程正在等待子进程退出,行:

printf("****END OUTPUT*********\n");

父进程和子进程都执行,所以你看到了两次。

【讨论】:

    【解决方案2】:

    您的 进程正在退出循环,但您的父进程继续运行。

    shell 的正常范例是让父进程读取和评估输入,并且只有在需要子进程时才会派生。

    使用该方法,父级将检测到exit 并在不创建子级的情况下完成。

    【讨论】:

      【解决方案3】:

      当你打印时

      {13160}$ 退出

      实际上,13160 是将由 fork 创建以处理退出命令的进程的父进程的 pid(要查看实际情况,请在 fork 之后打印子进程的 pid)。这将通过将标志设置为 0 来解析退出并退出。然后您将看到 ****END OUTPUT********* 两次。

      您必须记住,当您分叉时,内存不会与父级共享(在 Linux 中是这样,但它是写入时复制。这是我最后一次阅读它)所以当子级写入标志 = 0 时,父级将看不到这个值,所以它会再次循环。这就是为什么它再次要求输入。

      您处理关系的另一件事看起来像{13158}-&gt;{13159}-&gt;{13160}-&gt;... 由于根进程是 13158,我认为您想要做的是在每次输入后从根生成一个子进程。所以你可能想检查一下。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-01-25
        • 2017-04-18
        • 1970-01-01
        • 2020-01-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多