叉子永远不会进入孩子的过程 [英] Fork never enters child's process

查看:90
本文介绍了叉子永远不会进入孩子的过程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写模仿外壳行为的代码,特别是&和|.

I'm writing a code that mimics a shell behavior, specifically & and |.

我的函数接收用户命令,并检查是否有&最后,子进程应在后台运行,父进程不应等待其完成并继续执行命令.

My function receives user commands, and checks if there's an & at the end, then the child process should run in the background and the parent should not wait for it to finish and continue executing commands.

还应该检查是否有|.在输入数组中运行两个子进程,同时对它们的stdin和stdout进行管道传输.

Also it's supposed to check if there's a | in the input array and run two child processes while piping their stdin and stdout.

我已经实现了&的行为,但是每当我编译并运行代码时,我只会从父进程获取printf语句.

I have implemented the behavior for &, but whenever I compile and run my code, I only get the printf sentence from the parent's process.

我想听听如何解决此问题的想法,此外,我希望您对实施|提出任何建议. (烟斗)以及如何防止僵尸.

I would like to hear ideas how to fix this, in addition I would appreciate any suggestions regarding the implementation of | (pipes) and how to prevent zombies.

int process_arglist(int count, char** arglist) {
int pid = fork();
printf("%d", pid);
switch (pid) {
case -1:
    fprintf(stderr, "ERROR: fork failed\n");
    return 1;
    break;

case 0: // Son's proccess
    printf("I got to son");
    //check last arglist argument
    if (strcmp(arglist[count - 1], "&") == 0) {
        setpgid(0, 0);
        arglist[count - 1] = NULL;
        if (execvp(*arglist, arglist) < 0) {     //execute the command
            fprintf(stderr, "ERROR: execvp failed\n");
            exit(1);
        }
    } else { //There's no & at the end, look for pipes
        int i = 0;
        while (i < count) {
            if (strcmp(arglist[i], "|") == 0) {
                int pid2 = fork();
                if (pid2 < 0) {
                    //fork failed, handle error
                }
                if (pid2 == 0) { // Son's proccess

                } else { //Parent's code

                }
            }
        }
    }
    break;
    //in case no & and no |, call execvp

default: //Parent's code
    printf("I go to parent");
    return 1;
    break;
}
return 0;

}

输出始终为我去父母"

The output is always "I go to parent"

推荐答案

我假设您的代码适用于Linux或其他POSIX系统.阅读一些有关Linux编程的好书(也许旧的 高级Linux编程 ,可免费下载或更新).

I assume your code is for Linux or some other POSIX system. Read some good book on Linux programming (perhaps the old Advanced Linux Programming, freely downloadable, or something newer).

stdio(3)已缓冲,并且stdoutprintf通常(但不总是)是行缓冲的.出于效率原因而发生缓冲(调用 write(2)非常通常,例如每个输出字节一次,它非常慢;您应该更喜欢对几千字节的块执行write -s.

stdio(3) is buffered, and stdout and printf is often (but not always) line-buffered. Buffering happens for efficiency reasons (calling write(2) very often, e.g. once per output byte, is very slow; you should prefer doing write-s on chunks of several kilobytes).

顺便说一句,您最好处理系统调用的失败(请参见

BTW you'll better handle failure of system calls (see intro(2) and syscalls(2)) by using errno(3) thru perror(3) (or strerror(3) on errno). You (and the user of your shell) needs to be informed of the failure reason (and your current code don't show it).

我建议经常以\n结尾您的printf格式控制字符串(这在stdout是行缓冲的情况下有效)或调用

I recommend to often end your printf format control strings with \n (this works when stdout is line-buffered) or to call fflush(3) at appropriate places.

根据经验,我建议在每次调用

As a rule of thumb, I suggest doing fflush(NULL); before every call to fork(2).

您观察到的行为与以下假设相符:某些printf版本的数据保留在缓冲区中(例如stdout).

The behavior you observe is consistent with the hypothesis that some printf-ed data is staying in buffers (e.g. of stdout).

您可以在自己的计算机上使用 strace(1)程序(或其他程序,例如一些现有的shell程序)以了解完成了系统调用

You could use strace(1) on your program (or on other ones, e.g. some existing shell process) to understand what system calls are done.

您应该使用所有警告和调试信息进行编译(例如,使用 GCC gcc -Wall -Wextra -g),以改善您的代码以不发出警告,并且使用调试器gdb (小心,它可用于分叉过程.

You should compile with all warnings and debug info (e.g. gcc -Wall -Wextra -g with GCC), improve your code to get no warnings, and use the debugger gdb (with care, it can be used on forking processes).

我正在编写模仿外壳行为的代码

I'm writing a code that mimics a shell behavior

您可能正在编写一些shell.然后研究来启发现有的免费软件 shell的源代码(大部分(可能是全部)Linux外壳都是免费软件.

You probably are coding some shell. Then study for inspiration the source code of existing free software shells (most -probably all- Linux shells are free software).

对于实施|的任何建议,我将不胜感激. (烟斗)以及如何防止僵尸.

I would appreciate any suggestions regarding the implementation of | (pipes) and how to prevent zombies.

解释所有需要大量空间的内容(一本书的几个章节,或者一本书的整个章节),并且不适合此处或在任何其他论坛上使用.因此,阅读一本好的Linux 或POSIX 编程书.关于管道,请阅读 pipe(7)(应该是使用 pipe(2) 之前 fork).关于避免僵尸进程,您需要仔细调用

Explaining all that requires a lot of space (several chapters of a book, or perhaps, an entire book) and don't fit here or on any other forum. So read a good Linux or POSIX programming book. Regarding pipes, read pipe(7) (it should be created with pipe(2) before the fork). Regarding avoiding zombie processes, you need to carefully call waitpid(2) or some similar call.

这篇关于叉子永远不会进入孩子的过程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆