fork()函数

本文介绍了Linux系统中用于创建进程的fork()函数,详细解释了该函数的工作原理,包括如何返回两个不同的值给父进程和子进程,并通过示例代码展示了如何使用fork()。文章还提出了几个关于fork()函数使用的思考题,帮助读者更深入理解其行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


问题导入:大家应该都对进程有一个概念,我们从硬盘上找到我们写下的.c文件代码,在linux中我们通过输入驱动命令让预处理器、编译器、汇编器和连接器给我们最后生成一个可
执行的目标文件,然后再给一个执行命令,将这个可执行的文件加载进内存执行。就在可执行文件加载进内存的时候,生成一个新的进程,供cpu管理和控制它的执行。那这里就有一个疑问了,
这里cpu是自动为我们生成了一个进程,它是怎样生成的呢?我们自己能不能手动创建一个新的进程呢?
       
答案是肯定的,系统使用的是fork函数创建进程,fork是一个系统调用,如果我们想在自己的程序中手动的创建新进程,我们也可以使用这个函数。
首先,这个函数的声明是:pid_t fork(void);
使用fork()函数需要包含的头函数,pid_t是在头文件里定义的,所以这个文件也要包括。
函数的参数为空,不需要传入参数,但是这个函数的返回值很重要。调用fork()的函数我们称为父进程,而因为fork()而生成的另外一个进程称为子进程。父进程返回值为新进程的pid,而新进程返回值为0。 为什么一个函数调用可以返回两个值呢?
这是因为fork()一旦调用会产生两个一模一样的进程,所以在父进程中有一份自己的代码,而子进程中也复制了一份和父进程一样的代码,所以相当于在两个进程中执行一个代码, 那两个进程中每个进程都有自己的一个返回值,且仅返回了一个,这样的角度看,还是符合c语言的语法,函数只有能返回一个值。
还有一个小地方需要强调一下,在子进程赋值父进程的内容时, 程序计数器也会复制过去(也就是指向下一条待执行的指令)。为什么这样呢?
 因为如果我们的子进程又从main()的第一条指令执行,那么又会需要执行fork()这条指令(子进程内容和父进程完全一样),那子进程又会生成新进程,如此下去,岂不是 死循环了!
        那原理说的得差不多了,我们写一个简单的代码使用和测试一下吧。

运行结果:



这个代码和运行结果是不是证实了我上面所说的。因为一个程序运行if else语句只能进入一个,现在两个值却都能输出,正是因为我们产生了两个进程, getpid()意思是得到当前进程的pid号
还有一个需要注意的是大家是不是发现我们打印完父进程的信息,也 就是父进程结束之后,命令提示行就出来了,还没等子进程运行和输出完成。
这是因为我们的终端只能检测到当前运行的进程,对于fork()出来的子进程,它是察觉不到的,所以只要父进程一执行完成,它就认为进程已经执行完成,所以直接输出命令提示行。
        下面我们了解了fork()基本原理,我们就可以思考一些题目更加深入了解一下fork();
       
        题目1:int main()
              {
pid_t n;
               for(int i=0;i<2;i )
               {
                 if(fork())
                 {
                    printf("A\n");
                  }
else
                {
                   printf("B\n");
                 }
               }
     
              如果执行上面代码会输出什么?
              我们看图分析

首先进入 第一次循环i=0,这个时候fork()出了一个子进程,那这个 父进程的返回值当然是非0,所以 输出A(黑色字体),而生成的 子进程则返回值为 0输出B(第一行第二个框黑色字体),那复制过去所有内容一样,两个独立的进程的i为0的时候执行完了, 都要执行i为1时了。这个时候 原来的父进程在fork一次,它的返回值还是非0,所以 输出A(蓝色),而 新的子进程输出B(红色)。而 原来的子进程,因为也在调用了fork(),所以 它现在相对来说是父进程了输出A(蓝色),生成的 子进程 输出B(红色字体)。所以我们就会得到 3个A和3个B的输出,但是因为fork()之后的两个进程是独立的,所以我们不知道哪个进程运行结束的更早,也就 不知道具体的输出顺序
 
 题目2:
 int main()
              {
  pid_t n;
               for(int i=0;i<2;i )
               {
                 if(fork())
                 {
                    printf("A");
                  }
else
                {
                   printf("B");
                 }
               }
        如果我们每次输出不执行'\n'会发生什么呢?

       题目3:
      
       int main()
              {
  pid_t n;
               for(int i=0;i<2;i )
               {
                 if(fork())
                 {
                    printf("A\n");
                  }
else
                {
                   printf("B\n");
                 }
               }
      这样又会输出什么呢?
大家可以先想一下这两个思考题,如果想不到,请看下回分解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值