fork后printf如何输出

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

int main(void) 
{ 
    int i; 
    for(i=0; i<2; i++){ 
        fork(); 
        printf("-"); 
    } 

    return 0; 
}

本人思路:

答:三个
  因为是先fork,再printf,所以第一次fork创建的子进程的缓冲区中没有“-”,此时缓冲区中只有一个“-”,第二次进入创建再次进行fork,此时父进程的缓冲区中有一个“-”,fork之后,进行printf,第二个子进程中就有了一个”-“,此时父进程有两个,第二个子进程有一个,共三个。程序结束时,进程全部退出,刷新缓冲区,输出三个”-“。

实际测试:
这里写图片描述
原因:

错误分析:
  

* 不了解fork之后父子进程都会执行fork后面的代码,然后没有考虑到printf缓冲区的情况 *

如图:
这里写图片描述
  第一次父进程进入之后fork子进程子1,同事要记得父子进程都会执行fork之后的代码,所以此时父子都会printf“-”,此时是两个“-”
然后第二次fork,父进程再创建一个子进程子2,同时两个都打印printf“-”,
  子1进程fork孙子进程孙1,此时子1和孙1都打印“-”,此时共6个“-”;
  这也是理论情况下的,但是由于printf有自己的缓冲区,所以会多打印两个,即8个。,因为printf刷新缓冲区时不带’\n’时,是按全缓冲刷新的,即遇到文件结尾或缓冲区写满才会刷新,所以在fork时缓冲区作为一个进程PCB中的一部分也被子进程继承。
  

- 步骤:

  父创建子1,父和子1都打印“-“——2
  此时printf自己的缓冲区中有两个
  父进程再次创建子2,此时父进程的printf缓冲空间中有一个“-”,fork时被子2继承,所以子2的printf缓冲区中本来就有一个“-”,再加上自己打印的,共有两个,同理,子1fork孙1时,孙1继承子1的,也继承一个“-”,再打印一个,此时也多一个,共多两个。

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将 `printf()` 的输出信息输出到另一个 shell,可以使用管道来实现。具体步骤如下: 1. 创建一个管道,用于将 `printf()` 的输出信息传递给另一个 shell。 2. 创建一个子进程,在子进程中关闭管道的读端,并将标准输出重定向到管道的写端。 3. 在父进程中关闭管道的写端,并将标准输出重定向到另一个 shell 的输入端。 4. 在父进程中使用 `printf()` 函数输出信息,这些信息将被传递给子进程,并通过管道传递给另一个 shell。 以下是一个简单的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main() { int pipefd[2]; if (pipe(pipefd) == -1) { perror("pipe"); exit(EXIT_FAILURE); } pid_t pid = fork(); if (pid == -1) { perror("fork"); exit(EXIT_FAILURE); } else if (pid == 0) { // 子进程 close(pipefd[0]); // 关闭管道的读端 dup2(pipefd[1], STDOUT_FILENO); // 将标准输出重定向到管道的写端 execlp("/bin/sh", "sh", "-c", "cat", NULL); // 在子进程中执行 cat 命令 perror("execlp"); exit(EXIT_FAILURE); } else { // 父进程 close(pipefd[1]); // 关闭管道的写端 dup2(pipefd[0], STDIN_FILENO); // 将标准输入重定向到管道的读端 execlp("/bin/sh", "sh", NULL); // 在父进程中执行另一个 shell perror("execlp"); exit(EXIT_FAILURE); } return 0; } ``` 在该示例中,首先使用 `pipe()` 函数创建一个管道,然后创建一个子进程,在子进程中关闭管道的读端,将标准输出重定向到管道的写端,并通过 `execlp()` 函数执行 `cat` 命令。在父进程中,关闭管道的写端,将标准输入重定向到管道的读端,并通过 `execlp()` 函数执行另一个 shell。然后在父进程中使用 `printf()` 函数输出信息,这些信息将被传递到子进程中,并通过管道传递给另一个 shell。需要注意的是,在使用管道传递数据时,需要及时关闭管道的读端和写端,否则可能会造成死锁或数据丢失的情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值