fork()

fork系统调用

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

int main()
{
    pid_t pid;
    int count =0;
    pid = fork();
    if(pid < 0)
    {
        printf("error!");
    }
    else if(pid == 0)
    {
        printf("i am child %d 
",getpid());
        count++;
    }
    else
    {
        printf("i am father %d
",getpid());
        count++;
    }
  //两次输出的都是1 printf(
"count:%d ",count); return 0; }

fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
    1)在父进程中,fork返回新创建子进程的进程ID;
    2)在子进程中,fork返回0;
    3)如果出现错误,fork返回一个负值;

 fork出错可能有两种原因:
    1)当前的进程数已经达到了系统规定的上限,这时errno的值被设置为EAGAIN。
    2)系统内存不足,这时errno的值被设置为ENOMEM。

fork把进程当前的情况拷贝一份,不是从代码开始处拷贝的。一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。

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

int main()
{
    int i = 0;
    for(i = 0;i < 2;++i)
    {
        pid_t pid = fork();
        if(pid == 0)
        {
            printf("i = %d child %d %d
",i,getpid(),getppid());
        }
        else
        {
            printf("i = %d father %d childid = %d %d
",i,getpid(),pid,getppid());
        }
    }
    return 0;
}

输出:

i = 0 father 3020 childid = 3021 2650
i = 1 father 3020 childid = 3022 2650
i = 1 child 3022 1662
i = 0 child 3021 1662
i = 1 father 3021 childid = 3023 1662
i = 1 child 3023 1662

注意,上述进程如果跑完循环,就死亡了,这样子进程就没有父进程了,这在操作系统中是不被允许的 ,所以置为1662

对于这种N次循环的情况,执行printf函数的次数为2*(1+2+4+……+2N-1)次,创建的子进程数为1+2+4+……+2N-1

#include <unistd.h>
#include <stdio.h>
int main() {
    pid_t fpid;//fpid表示fork函数返回的值
    //printf("fork!");
    printf("fork!/n");
    fpid = fork();
    if (fpid < 0)
        printf("error in fork!");
    else if (fpid == 0)
        printf("I am the child process, my process id is %d/n", getpid());
    else
        printf("I am the parent process, my process id is %d/n", getpid());
    return 0;
}

    执行结果如下:
    fork!
    I am the parent process, my process id is 3361
    I am the child process, my process id is 3362 
    如果把语句printf("fork!/n");注释掉,执行printf("fork!");
    则新的程序的执行结果是:
    fork!I am the parent process, my process id is 3298
    fork!I am the child process, my process id is 3299 
    程序的唯一的区别就在于一个/n回车符号,为什么结果会相差这么大呢?
    这就跟printf的缓冲机制有关了,printf某些内容时,操作系统仅仅是把该内容放到了stdout的缓冲队列里了,并没有实际的写到屏幕上。但是,只要看到有/n 则会立即刷新stdout,因此就马上能够打印了。
    运行了printf("fork!")后,“fork!”仅仅被放到了缓冲里,程序运行到fork时缓冲里面的“fork!”  被子进程复制过去了。因此在子进程度stdout缓冲里面就也有了fork! 。所以,你最终看到的会是fork!  被printf了2次!!!!
    而运行printf("fork! /n")后,“fork!”被立即打印到了屏幕上,之后fork到的子进程里的stdout缓冲里不会有fork! 内容。因此你看到的结果会是fork! 被printf了1次!!!!

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

int main()
{
    fork();
    fork()&&fork()||fork();
    fork();
    printf("+
");
    return 0;
}

总共20个进程,除去main进程,还有19个进程

第一个fork和最后一个fork肯定是会执行的。
    主要在中间3个fork上,可以画一个图进行描述。
    这里就需要注意&&和||运算符。
    A&&B,如果A=0,就没有必要继续执行&&B了;A非0,就需要继续执行&&B。
    A||B,如果A非0,就没有必要继续执行||B了,A=0,就需要继续执行||B。
    fork()对于父进程和子进程的返回值是不同的,按照上面的A&&B和A||B的分支进行画图,可以得出5个分支。

http://blog.csdn.net/jason314/article/details/5640969

原文地址:https://www.cnblogs.com/ljygoodgoodstudydaydayup/p/5421284.html