【问题标题】:Unix fork() system call what runs when?Unix fork() 系统调用什么时候运行?
【发布时间】:2012-02-10 09:59:48
【问题描述】:
void child(int pid){
    printf("Child PID:%d\n",pid);
    exit(0);    
}
void parent(int pid){
    printf("Parent PID:%d\n",pid);
    exit(0);
}

void init(){
    printf("Init\n");//runs before the fork
}


int main(){

    init();//only runs for parent i.e. runs once
    printf("pre fork()");// but this runs for both i.e. runs twice
    //why???

    int pid = fork();

    if(pid == 0){
        child(pid); //run child process
    }else{
        parent(pid);//run parent process
    }
    return 0;
}

输出:

Init
pre fork()Parrent PID:4788
pre fork()Child PID:0

我在 Unix 操作系统(在我的例子中是 Ubuntu)中有一个进程。我一生都无法理解这是如何工作的。我知道fork() 函数将我的程序分成两个进程,但从哪里开始?它是否会创建一个新进程并再次运行整个 main 函数,如果是,为什么 init() 只运行一次,printf() 运行两次?

为什么printf("pre fork()"); 运行两次而init() 函数只运行一次?

【问题讨论】:

  • 这能回答你的问题吗? printf anomaly after "fork()"
  • @NateEldredge 9 年前我接受的答案回答了我的问题:P 但是谢谢,我想:P
  • 抱歉打扰了,我只是想标记这个问题的一些重复项。

标签: c linux unix fork


【解决方案1】:

在分叉之前只有一个进程。也就是说,该路径只执行一次。在 fork 之后有 2 个进程,因此该系统调用之后的代码由两个进程执行。您忽略的是两者都终止并且都将调用exit

在您的代码中,您没有刷新stdio。所以两个进程都这样做(退出刷新 stdio 缓冲区) - 这就是你看到该输出的原因。

试试这个:

printf("pre fork()\n");
                  ^^ should flush stdout

或许

printf("pre fork()\n");
fflush(stdout);

【讨论】:

  • 哇,这太微妙了!来自我的 +1!
  • 简单地放入换行符并不一定会刷新缓冲区。使用重定向到常规文件的 stdout 运行代码,您将看到完全相同的行为。默认情况下,stdout 不是 行缓冲,除非它是 tty。
  • @WilliamPursell 完全正确。即使目标是 tty,标准也不保证 \n 会触发刷新。
猜你喜欢
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-24
  • 2019-10-25
  • 2015-12-16
  • 2016-04-30
相关资源
最近更新 更多