Linux系统应用编程 --- 进程原语(一)

进程原语一. fork函数

1. 函数原型

pid_t fork(void);

子进程复制父进程的0到3g空间和父进程内核中的PCB,但id号不同。

2. 以具体的程序讲解fork函数特点

第一段代码

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
 
int main(void)
{     
       //fork创建一个新进程
       pid_t p1 = -1;
 
       //fork之前的操作只有父父进程才有
       p1 = fork();    //调用一次fork函数会返回两次
      
       if(p1 == 0)
       {
              //这里一定是子进程
              //先sleep一下,让父进程先死
              sleep(1);
          
              printf("子进程, pid = %d.\n", getpid());
              printf("子进程, p1 = %d.\n", p1);
              printf("子进程中父进程的ID = %d.\n", getppid());
       }
       if(p1 > 0)
       {
              //这里一定是父进程
              printf("父进程, pid = %d.\n", getpid());
              printf("父进程, p1 = %d.\n", p1);
       }
 
       if(p1 < 0)
       {
 
              //这里一定是出错了
       }
 
       //在这里的操作,父子进程都有
       //printf("hello world, pid = %d.\n", getpid());
      
       return 0;
}

输出结果如下:

结论:

结论:

(1)fork函数调用一次会返回两次,返回值等于0的就是子进程,返回值大于0的就是父进程

(2)fork的返回值在子进程中等于0, 在父进程中返回值等于本次fork创建的子进程的PID

(3)这里在子进程中打印父进程PID,为什么跟在父进程中打印父进程的PID结果不一样?

是因为在执行的时候,父进程先执行完,然后子进程就没有父进程了;这是在子进程中打印的父进程PID就是init进程

 

第二段代码

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
 
int main(void)
{
       pid_t pid ;
       //调用一次返回2次,在父进程返回子进程的PID,在子进程中返回0
      
       int n = 10;
       pid = fork();
      
       if(pid > 0)
       {/*in parent*/
              while(1)
              {
                     printf("I am parent %d\n", n++);
                     printf("my pid = %d.\n", getpid());
                     printf("my parent pid = %d.\n", getppid());
                     sleep(1);
              }
       }
 
       else if(pid == 0)
       {/*in child*/
              while(1)
              {
                     printf("I am child %d\n", n++);
                     printf("my pid = %d.\n", getpid());
                     printf("my parent pid = %d.\n", getppid());
                     sleep(3);
 
              }
       }
 
       else
       {
              perror("fork");
              exit(0);
       }
 
       return 0;
}

结论:

(1)父子进程中n值分别独立加,说明子进程从父进程中克隆过来的数据,已经不是共享的了。两者有自己独立的空间。

(2)0-3G放应用层代码,子进程直接从父进程中拷贝,3-4G是内核空间

(3)读时共享,写时复制(copy on write)(好处:节省物理内存开销,省去直接复制的时间)

fork函数创建子进程之后,如果只是用返回值去区分父子进程,这样的方式效率太低,下面会介绍更好的方法!!!

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Overboom

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值