Linux学习笔记11 ——fork

1,函数原型

#includ<unistd.h>
pid_t fork(void);

函数执行的效果:

创建一个子进程。该子进程是原先进程的副本,子进程获得父进程数据空间、堆、栈的副本,而不是共享它们。所以子进程不能直接修改父进程里的变量值。父子进程共享的是代码的正文段。注意共享的是整个代码段,但执行的话当然是fork之后的部分。不过如果i使用goto语句或其他方法的话,也可以让子进程执行到fork之前的语句。

函数的返回值:

与其他函数不同,这个函数调用一次会返回两次!子进程里返回一次,父进程里也会返回一次。子进程里返回值为0,父进程里返回值为子进程的pid,出错时返回负数。可以通过返回值来判断当前位于父进程还是子进程。

fork()之后的代码,父进程与子进程都会执行,并且不确定哪个进程先执行。

2,例子:

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

int  globvar = 6;
char buf[] = "a write to stdout\n";

int main(){
    // 8.3 fork
    int var = 88;
    int pid;
    
    // write无缓冲
    if(write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1){
        printf("Error!\n");
    }
    
    //标准IO,输出到终端行缓冲,输出到文件全缓冲
    printf("before fork\n");
    
    //开始产生子进程
    if((pid = fork()) < 0){
        printf("fork error!");        
    } else if(pid == 0){   // child process,子进程返回0
        globvar++;
        var++;
    } else {               // parent process,父进程返回子进程的ID
        sleep(2);
    }
    
    //观察子进程与父进程里的变量值
    printf("pid = %d, globvar = %d, var = %d\n", getpid(), globvar, var);
    return 0;
}

正常执行,执行的效果是:

可以看到父子进程里,变量的值是不同的!

这也就是前面说的,子进程只是获得了父进程数据空间、堆、栈的副本,而不是父子进程共享它们。所以子进程里的修改并不影响父进程里的变量的值。

将结果重定向到文件,执行效果如下:

可以看到最明显的区别就是“before fork”被打印了两次!!而write仍然只执行了一次。

为什么会这样呢?

因为write是系统调用,永远都是无缓冲的,两次执行效果一致。

但是,printf是标准IO,其输出到终端的时候是行缓冲,所以第一次在执行fork执行就会输出到屏幕。

但是当输出到文件时,其变成了全缓冲。在执行fork前其并不会写文件,内容存储在缓冲区中。然后执行fork,复制出一个子进程。此时,父进程的缓冲区里的内容也同样被复制一份到了子进程。所以父进程与子进程的缓冲区里都有“before fork”这段字符串。当每个进程终止时,其缓冲区里的内容都会写入文件。因此“before fork”就被写了两次。

这个例子也说明,子进程能获得父进程的缓冲区(数据空间)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值