Linux fork()

函数介绍

pid_t fork(void) 复制当前进程,返回值类型为pit_t(相当于int类型)表示进行的pid,在父进程中返回值为子进程的pid 其大于0,在子进程中,其返回值为0,若返回值小于0 表示创建子进程失败。

分析:创建子进程相当于复制了父进程的pcb,pcb在计算机中类似于链表一样串接在一起,所以父进程中返回的pid指向子进程,而子进程返回的pid为0,类似于指向NULL。

创建失败的原因:

  • 当前进程数达到上限
  • 系统内存不足

注意:子进程虽然有和父进程一样的pcb,但是每个进程的pid都是不一样的,子进程的pid一般 =父进程的pid +1 ,另外父子进程代码相同,数据独享

例:
下面两段代码输出结果相同

int main()
{
int ret = fork();
//父进程中getpid()为父进程pid ,父进程中ret返回值为子进程pid
//子进程中getpid()为子进程pid,子进程中ret返回值为 0
printf("hello proc : %d!, ret: %d\n", getpid(), ret);
sleep(1);
return 0;
}
int main()
{
int ret = fork();
if(ret < 0){
perror("fork");
return 1;
}
else if(ret == 0){ //child
printf("I am child : %d!, ret: %d\n", getpid(), ret);
}else{ //father
printf("I am father : %d!, ret: %d\n", getpid(), ret);
}
sleep(1);
return 0;
}

父子进程代码相同,数据独享

  1 #include <stdio.h>
  2 #include <sys/types.h>
  3 #include <unistd.h>
  4 int main()
  5 {
  6         int ret = fork();
  7         int count = 100;
  8         if(ret < 0){
  9                 perror("fork");
 10                 return 1;
 11         }
 12         else if(ret == 0){ //child
 13                 printf("I am child : %d!, ret: %d\n", getpid(), ret);
 14                 count = 20;
 15                 printf("count = %d\n",count);
 16         }
 17         else{
 18          //father
 19                 sleep(3);
 20                 printf("I am father : %d!, ret: %d\n", getpid(), ret);
 21                 printf("count = %d\n",count);
 22         }
 23         sleep(1);
 24         return 0;
 25 }

输出结果为
在这里插入图片描述

fork进阶知识

int main(void)  
{  
   int i=0;  
   printf("i son/pa ppid pid  fpid/n");  
   //ppid指当前进程的父进程pid  
   //pid指当前进程的pid,  
   //fpid指fork返回给当前进程的值  
   for(i=0;i<2;i++){  
       pid_t fpid=fork();  
       if(fpid==0)  
           printf("%d child  %4d %4d %4d/n",i,getppid(),getpid(),fpid);  
       else  
           printf("%d parent %4d %4d %4d/n",i,getppid(),getpid(),fpid);  
   }  
   return 0;  
}

输出结果为:
在这里插入图片描述
分析:

	   for(i=0;i<2;i++){ 
       	 pid_t fpid=fork();  
      	 if(fpid==0)  
            printf("%d child  %4d %4d %4d/n",i,getppid(),getpid(),fpid);  
         else  
           printf("%d parent %4d %4d %4d/n",i,getppid(),getpid(),fpid);  
   } 

i = 0时 当前进程pid = 6912 ,当前进程父进程2811 当前进程子进程6913
进程6912 进入下一次循环 i = 1 ,当前进程 6912 ,创建的子进程6914
(当前进程6912执行完毕,释放资源) 6912的子进程6914变成孤儿进程 6912父进程变为1
i = 0 6913进程也变成孤儿进程,父进程变为1 fpid = 0
i = 1此时6913变成父进程 fork子进程6918 6913执行完毕释放
6918变成孤儿进程 父进程为1

修改一下代码,在父进程前面在wait(NULL)等待子进程结束

  1 #include <unistd.h>
  2 #include <stdio.h>
  3 int main(void)
  4 {
  5         int i = 0;
  6         printf("i son/pa ppidt pid fpid\n");
  7         for(i = 0;i<2;i++)
  8         {
  9                 int fpid = fork();
 10                 if(fpid== 0){
 11                 //      sleep(2);
 12                         printf("%d child %4d %4d %4d\n",i,getppid(),getpid(),fpid);
 13                 }
 14                 wait(NULL);
 15         	    if(pid>0) {
 16                  printf("%d parent %4d %4d %4d\n",i,getppid(),getpid(),fpid);
 17      	  }
 18         }
 19         return 0;
 20 }
 21 

在这里插入图片描述
分析:
i = 0 父进程建立子进程 ,因为父进程阻塞所以子进程先运行,此时的进程是7348
由于wait的阻塞,子进程继续 此时i= 1 7348变为父进程 生成子进程7349 同样父进程7348被阻塞 当子进程7349 执行结束后 执行其父进程7348

发布了89 篇原创文章 · 获赞 11 · 访问量 5309

猜你喜欢

转载自blog.csdn.net/weixin_44997886/article/details/104280447