fork

来源:互联网 发布:手机查看电脑桌面软件 编辑:程序博客网 时间:2024/06/14 13:35
fork

由fork创建的新进程被称为子进程(child process)。

fork 函数被调用一次,但返回两次。两次返回的区别是子进程的返回值是0, 而父进程的返回值则是新建子进程的进程ID,由此可以区分父子进程。然后子进程和父进程继续执行fork调用之后的指令。子进程是父迸程的副本,子进程获得父进程数据空间、堆和栈的副本。注意,这是子进程所拥有的副本.父进程和子进程并不共享这些存储空间部分。

一般来说,在fork 之后是父迸程先执行还是子进程先执行是不确定的,这取决于内核所使用的调度算法。如果要求父进程和子进程之间相互同步,则要求某种形式的进程间通信。
int globvar = 6;char buf[] = "a write to stdout\n";int main(void){    int var = 88;    pid_t pid;    if(write(STDOUT_FILENO , buf , sizeof(buf) - 1) != (sizeof(buf) - 1))//write直接写到了终端,不带缓冲功能,所以不论输出到终端或者重定向输出到文件,都立即直接输出。        err_sys("write error");    printf("before fork");//输出到终端设备的时候进行行缓冲并且通过\n冲刷了行缓冲,直接输出到了终端.                          //输出到文件的时候是全缓冲.结束或者全满的时候输出.    if((pid = fork()) < 0)        err_sys("fork error");    else if(pid == 0){        globvar++;        var++;    }    else{        sleep(2);        globvar *= globvar;        var = var + globvar;    }    printf("pid = %ld , glob = %d , var = %d\n",(long)getpid() , globvar , var);    exit(0);}

直接执行输出到终端:
a write to stdout
before fork
pid = 4550 , glob = 7 , var = 89 (子进程)
pid = 4549 , glob = 36 , var = 124(父进程)
重定向输出到文件tmp.out里面内容:
a write to stdout
before fork
pid = 4622 , glob = 7 , var = 89
before fork
pid = 4621 , glob = 36 , var = 124

两个进程相互独立,都执行了fork之后的语句,通过判断pid的值,来区别父子进程所执行的不同部分。

对于终端,printf是行缓冲,可以通过换行符冲刷缓冲区然后显示出来,所以before fork显示一次。而重定向到文件,fork之后,父进程输出缓冲区含有第一次printf的内容(因为没有输出);子进程是父进程副本,所以其缓冲区一样有。最后两者在执行exit(0)之后,同时输出两次printf的内容。

原创粉丝点击