c - fork() 系统调用和 while 循环(第 2 部分)

标签 c linux fork system-calls

有谁知道为什么当我运行这段代码时 printf("Type q to quit") 行在终端中打印两次:

#include <stdio.h>
#include <unistd.h>

int main (int argc, char *argv[])
{
    char run[2];
    run[0]='a';
    int pid=0;
    while (run[0]!= 'q')    
    {
        printf("Type q to quit \n");
        fgets (run, 2, stdin);
  
        pid=fork();
        //wait();
        if(pid==0) { break;}
    }
}

我希望 child 从循环中跳出,而 parent 继续循环(以创建新的 child )。如果我调用 wait(),无论我是否输入 'q',执行都会在第一次迭代后结束。否则它会按预期工作,但每次都会打印两次 "Type q to quit" 行。为什么会这样?

最佳答案

你有三个错误。首先,用户在任何字母后键入的回车算作输入。假设用户每行只输入一个字符,您的 fgets 调用将交替返回您关心的字符和返回 '\n'。在每次迭代中,您需要读取并丢弃字符,直到到达每行输入的末尾。这就是导致双重打印输出的原因。

其次,您需要测试从 stdin 读取和调用 fork 之间的 'q' ;现在,你在阅读了 'q' 之后再次 fork。现在这是不可见的,但是一旦子进程开始做一些有用的事情就不会了。

第三,如果用户输入 ^D,这个程序将进入无限循环,因为你没有检查 EOF。

将它们放在一起,更正后的代码如下所示。我还修复了一些样式缺陷,并进行了安排,以便父进程立即退出而不是退出 for 循环;这意味着当控制到达标有注释的点时,您知道您处于子进程中,而不是在父进程中。

#include <stdio.h>
#include <unistd.h>

int
main(void)
{
    pid_t pid;
    int c;
    for (;;)
    {
        puts("Type q to quit");
        c = getchar();

        if (c == 'q')
            return 0;
        if (c == '\n')
            continue;
        while (c != EOF && c != '\n')
            c = getchar();
        if (c == EOF)
            return 0;

        pid = fork();
        if (pid == 0)
            break;
        else if (pid == -1)
        {
            perror("fork");
            return 1;
        }
    }

    /* control reaches this point only in child processes */
    return 0;
}

关于c - fork() 系统调用和 while 循环(第 2 部分),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19549070/

相关文章:

linux - 使用 Pip 安装 Twilio 时遇到问题

aws 上的 linux 权限 : basic

php - 带有 curl --interface 或 CURLOPT_INTERFACE 的 SO_BINDTODEVICE

c++ - 如何在 Linux 上调试 native 代码时自动附加到多个子进程?

javascript - 是什么原因导致node.js处理移除多线程状态的阻塞状态?

c - 双链表不能正常工作,C

python - 我可以将串行对象转换为文件描述符并将其传递给 C 程序吗?

c - fork() 的异步信号安全

c - 我应该在这段 C 代码中使用指针吗?在哪里?

c - C 中的 MQTT TLS session 恢复