父进程和子进程

作者: b6aed1af4328 | 来源:发表于2016-11-30 21:12 被阅读8次

子进程由父进程fork而来,拷贝父进程的全部代码,但执行时是选择执行的:从fork后开始执行。比如父进程第一次fork产生的子进程,在第二次fork后变成了父进程,也产生了一个子进程,而不会去执行第一次fork。
子进程继承了父进程的一切。也就是说,子进程虽然没有执行父进程fork之前的代码,但结果是和执行了fork之前的代码一样。
在fork前后打开文件,子进程和父进程的文件描述符一样,file结构体里的引用加1。fork前打开文件,子进程和父进程用同一文件指针,fork后打开文件,子进程和父进程使用不同的文件指针。
使用追加的方式打开文件,文件没有数据写入时,文件指针的位置在文件头,有数据写入,文件指针移到文件尾。
fork后打开文件

#include<unistd.h>
#include<stdio.h>
#include<string.h>
//#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<dirent.h>

#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
                   
//
//
int main()
{
    int i1=0;
 //   while(1)
   // {
        pid_t pid=-1;
        int fd=-1;
       
           
        pid=fork();
        printf("&i1=%p\n",&i1);
        printf("fd=%d\n",fd);
        printf("songshiqi\n");
         fd=open("tea.info",O_RDWR|O_CREAT|O_APPEND);
        if(fd==-1)
        {
                printf("打开失败\n");
                return -1;
        }
        int ret1=lseek(fd,0,SEEK_CUR);
        printf("ret1=%d\n",ret1);
        int iNum=0;
        int i=0;
        char caData[32]={'\0'};
        if(pid>0)//父进程
        {

            printf("&i1=%p\n",&i1);
            printf("fd=%d\n",fd);
            while(1)
            {
                i1++;
                printf("i1=%d\n",i1);
                if(i1==10)
                {
                    return 0;
                }
                sleep(1);
          
           int ret1=lseek(fd,0,SEEK_CUR);
          printf("fujincheng ret1=%d\n",ret1);
             int ret=-1;
            ret=write(fd,"333",3);
            if(ret==-1)
            {
                printf("写入失败\n");
                return -1;
            }
            printf("成功写入%d\n",ret);
         //   close(fd);
            }
            close(fd);
        }
        else if(pid==0)//子进程
        {
           printf("fd=%d\n",fd);
            printf("进入子进程\n");
            printf("&i1=%p\n",&i1);
            while(1)
            {
                i1++;
                printf("i1=%d\n",i1);
            if(i1>=10)
            {
                return 0;
            }

               // printf("进入循环\n");
                sleep(2);
         /*  int fd=-1;
            fd=open("tea.info",O_RDWR|O_CREAT);
            if(fd==-1)
            {
                printf("打开失败\n");
                return -1;
            }*/
            int ret=-1;
            ret=lseek(fd,0,SEEK_CUR);
            if(ret==-1)
            {
                printf("失败\n");
                return -1;
            }
            printf("该文件有%d字节大小\n",ret);
     //       close(fd);
            }
            close(fd);
        }
        else if(pid==-1)//创建进程失败     子进程 父进程完整拷贝  
        {
            printf("fork\n");
            return -1;
        }

 /*       for(;i<iNum;i++)
        {
            printf("%s",caData);
        }
        printf("hello wolrd1\n");
        while(1)
        {
            sleep(2);
        }*/
        close(fd);
    return 0;
}

fork前打开文件

#include<unistd.h>
#include<stdio.h>
#include<string.h>
//#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<dirent.h>


#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
                   
int main()
{
    int i1=0;
 //   while(1)
   // {
        pid_t pid=-1;
        int fd=-1;
        fd=open("tea.info",O_RDWR|O_CREAT);
        if(fd==-1)
        {
                printf("打开失败\n");
                return -1;
        }  
        pid=fork();
        printf("&i1=%p\n",&i1);
        printf("fd=%d\n",fd);
        printf("songshiqi\n");
        
        int iNum=0;
        int i=0;
        char caData[32]={'\0'};
        if(pid>0)//父进程
        {

            printf("&i1=%p\n",&i1);
            printf("fd=%d\n",fd);
            while(1)
            {

                i1++;
                printf("i1=%d\n",i1);
                if(i1==10)
                {
                    return 0;
                }
                sleep(1);
                    int ret2=lseek(fd,0,SEEK_CUR);
            printf("fu ret2=%d\n",ret2);
          
             int ret=-1;
            ret=write(fd,"333",3);
            if(ret==-1)
            {
                printf("写入失败\n");
                return -1;
            }
            printf("成功写入\n");

            ret2=lseek(fd,0,SEEK_CUR);
            printf("fu ret2=%d\n",ret2);
         //   close(fd);
            }
            close(fd);
        }
        else if(pid==0)//子进程
        {
           printf("fd=%d\n",fd);
            printf("进入子进程\n");
            printf("&i1=%p\n",&i1);
            while(1)
            {
                i1++;
                printf("i1=%d\n",i1);
            if(i1>=10)
            {
                return 0;
            }

               // printf("进入循环\n");
                sleep(2);
         /*  int fd=-1;
            fd=open("tea.info",O_RDWR|O_CREAT);
            if(fd==-1)
            {
                printf("打开失败\n");
                return -1;
            }*/
             int ret2=lseek(fd,0,SEEK_CUR);
            printf("zi ret2=%d\n",ret2);

            int ret=-1;
            ret=lseek(fd,0,SEEK_CUR);
            if(ret==-1)
            {
                printf("失败\n");
                return -1;
            }
            printf("该文件有%d字节大小\n",ret);
     //       close(fd);
            }
            close(fd);
        }
        else if(pid==-1)//创建进程失败     子进程 父进程完整拷贝  
        {
            printf("fork\n");
            return -1;
        }

 /*       for(;i<iNum;i++)
        {
            printf("%s",caData);
        }
        printf("hello wolrd1\n");
        while(1)
        {
            sleep(2);
        }*/
        close(fd);
    return 0;
}

文件一次循环使用3次fork,第一次fork产生1个父进程和1个子进程,第二次fork产生2个父进程和2个子进程,第3次fork产生4个父进程和4个子进程,和上面的理论相符。
一次fork3次循环产生的效果一样。
一次循环3次fork:

#include<unistd.h>
#include<stdio.h>
#include<string.h>
int main()
{
 //   while(1)
   // {
        pid_t pid=-1;
        pid=fork();
        int iNum=0;
        int i=0;
        char caData[32]={'\0'};
        if(pid>0)//父进程
        {
            printf("this is parent process\n");
            strcpy(caData,"this is parent process\n");
            printf("the parent:%d\n",pid);
            iNum=3;
    
        }
        else if(pid==0)//子进程
        {
            printf("this is child process\n");
            strcpy(caData,"this is child process\n");
             printf("the child:%d\n",pid);
            iNum=6;
        }
        else if(pid==-1)//创建进程失败     子进程 父进程完整拷贝  
        {
            printf("fork\n");
            return -1;
        }

//        for(;i<iNum;i++)
 //       {
 //           printf("%s",caData);
 //       }
        printf("hello wolrd1\n");
        sleep(6);
            pid_t pid1=-1;
        pid1=fork();
        int iNum1=0;
        int i1=0;
        char caData1[32]={'\0'};
        if(pid1>0)//父进程
        {
            printf("this is parent process\n");
            strcpy(caData1,"this is parent process\n");
            printf("the parent:%d\n",pid1);
            iNum1=3;
    
        }
        else if(pid1==0)//子进程
        {
            printf("this is child process\n");
            strcpy(caData1,"this is child process\n");
             printf("the child:%d\n",pid1);
            iNum1=6;
        }
        else if(pid1==-1)//创建进程失败     子进程 父进程完整拷贝  
        {
            printf("fork\n");
            return -1;
        }
        printf("hello wolrd2\n");
             pid_t pid12=-1;
        pid12=fork();
        int iNum12=0;
        int i12=0;
        char caData12[32]={'\0'};
        if(pid12>0)//父进程
        {
            printf("this is parent process\n");
            strcpy(caData12,"this is parent process\n");
            printf("the parent:%d\n",pid12);
            iNum12=3;
    
        }
        else if(pid12==0)//子进程
        {
            printf("this is child process\n");
            strcpy(caData12,"this is child process\n");
             printf("the child:%d\n",pid12);
            iNum12=6;
        }
        else if(pid12==-1)//创建进程失败     子进程 父进程完整拷贝  
        {
            printf("fork\n");
            return -1;
        }
        printf("hello wolrd3\n");
    //    sleep(6);
        while(1)
        {
            sleep(2);
        }
     //     printf("hello wolrd\n");
    //      sleep(4);
     //     printf("songshiqi\n");
  //  }
        return 0;
}

僵尸进程的解决办法一是父进程使用wait函数,执行阻塞直到子进程结束获得子进程的退出状态,并对子进程做清理工作;二是父进程尽快执行完,由祖宗进程来完成善后。

相关文章

  • 进程管理

    进程(process)通常可被归为父进程和子进程。 父进程负责创建和结束子进程。子进程调用exit()并不能立即结...

  • Linux回收子进程

    孤儿进程 孤儿进程: 父进程先于子进程结束,则子进程成为孤儿进程,子进程的父进程成为init进程,称为init进程...

  • 父进程和子进程

    子进程由父进程fork而来,拷贝父进程的全部代码,但执行时是选择执行的:从fork后开始执行。比如父进程第一次fo...

  • 父进程和子进程

    使用fork函数创建子进程后,子进程和父进程就同时运行,运行时间和顺序取决于处理器的调度进制。 代码 运行结果:

  • 孤儿进程和僵尸进程

    基本概念 在unix/linux中,正常情况下,子进程是通过父进程创建,子进程再创建新的进程。子进程的结束和父进程...

  • node.js略知一二之child_process

    子进程与父进程分离 正常情况下,父进程结束后,子进程都会被终结。如果我们想要子进程和父进程进行分离,可以使用spa...

  • fork 进程测试 copy-on-write

    父进程 fork 子进程后,子进程通过 copy-on-write 模式获得父进程内存,也就是子进程共用了大部分父...

  • 僵尸进程的产生和防范

    僵尸进程 僵尸进程的产生 fork产生的父进程和子进程有退出的先后顺序,如果子进程在父进程前退出就会产生,而父进程...

  • Linux进程

    一、概念 在unix/linux中,正常情况下,子进程是通过父进程创建的,子进程在创建新的进程。子进程的结束和父进...

  • 示例说明僵尸进程的危害及解决方法

    简述 首先简要说明下僵尸进程和孤儿进程的概念(前提都是父进程调用fork产生子进程) 僵尸进程:子进程终止,父进程...

网友评论

    本文标题:父进程和子进程

    本文链接:https://www.haomeiwen.com/subject/amytmttx.html