【Linux】如何创建进程?

       🔥🔥 欢迎来到小林的博客!!
      🛰️博客主页:✈️林 子
      🛰️博客专栏:✈️ 小林的Linux之路
      🛰️社区 :✈️ 进步学堂
      🛰️欢迎关注:👍点赞🙌收藏✍️留言

fork函数是什么?

fork函数是一个系统调用接口,我们可以通过man 2 fork 查看它。

在这里插入图片描述
而这个函数的作用就是创建一个子进程。接下来我们好好探索进程的创建。

fork创建进程

fork是一个创建子进程的函数。我们写一个程序来演示一下。

在这里插入图片描述

然后我们编译运行。

我们会发现,打印了2次hello world。

在这里插入图片描述

为什么会打印2次helloworld?因为fork函数它又新建了一个新的进程。这个新的继承继承了它的父进程。而fork的返回值。如果是子继承返回,会返回0。如果是父进程返回,会返回子进程的pid。如果进程创建失败,返回-1。

所以我们改造一下我们的程序。

在这里插入图片描述

这个程序就把子进程和父进程分流了。如果是子进程,则输出 child process pis is 子进程的pid。如果是父进程则输出父进程的pid。为了方便观察,每次执行完睡眠一秒

我们编译执行

在这里插入图片描述

我们会发现,父进程的pid是10967,子进程的pid是10968。我们可以来查看一下进程,输入命令: ps ajx | head -1 && ps ajx | grep "myprocess"查看

在这里插入图片描述

我们发现,我们查看的时候会出现多列数据。第一列代表管理进程的pid,就是管理当前进程的进程的pid。第二列是当前进程的pid,第三列是父进程的pid。

那么我们kill -9 10968,杀掉子进程看看。

我们杀掉子进程后,就只有父进程再运行了,所以只输出father process。

在这里插入图片描述

这也可以说明,这个程序是有2个进程再执行的。那么这时候就有疑问了。

两个返回值

这时候我们就有疑问了,为什么fork函数有2个返回值?明明只调用了一次,而2个pid的值却互不相同。

要搞清楚这个问题,我们要先弄清楚,fork创建一个新进程。这个新进程的数据是从哪来的?

再上篇进程概念我提到过,**进程 = 描述进程的结构体 + 数据代码 ** 。那么fork创建进程的时候,这个新进程的内容,是怎么来的呢?

子进程的数据来源

子进程的数据来源

我们上面打印了2次hello word。就证明了,子进程和父进程的数据和代码是共享的。前提是进程的数据在后续不会发生修改!如果发生修改,那么父进程的数据会发生一次实时拷贝,随后把拷贝的代码数据交给子进程!

所以: 当进程里数据没有发生修改时。那么子进程和父进程共享代码和数据!如果有一个进程的数据发送了修改,那么会对数据发送写实拷贝,而代码依旧是共享的

在这里插入图片描述

如果发生修改,那么父进程的代码数据会进行一份实时拷贝,给子进程。

在这里插入图片描述

子进程结构体来源

子进程结构体来源

那么fork创建的子进程,描述它的结构体是怎么来的呢?

是根据父进程结构体模板初始化来的。

如何理解这句话,打个比方。你爸爸生出了你,那你的数据怎么来的?假如你爸爸姓王,那么你肯定也姓王。所以你的数据是根据你爸爸的模板来起的。所以这里的子进程也是一样的,它的结构体数据是根据它的父进程初始化的。但肯定也不是一模一样,pid,ppid…肯定都是子进程独有的。

为什么会有2个返回值?

现在我们再回到之前的问题,为什么fork会返回两个值?我们不不妨这样子想,当一个函数执行到return的时候。那么它的功能是不是都已经执行完了?功能都执行完了,就意味着子进程在fork函数return之前就已经创建好了,既然子进程已经创建好了,那么就会继承父进程的代码和数据。那么父进程的程序计数器也会被继承下来,这就意味着子进程也有一个fork函数,并且能返回一个值回去。

所以子进程也会发生return操作。而我们的一个父进程是可以有多个子进程的,那么父进程就要通过子进程的pid来找到子进程,所以fork函数会给父进程返回子进程的pid。而子进程一定只有一个父进程,可以直接通过ppid找到父进程,所以并不需要返回父进程的pid,所以fork函数会给子进程返回0。

父进程给子进程的返回值是0,子进程给父进程返回其pid值(大于0),创建失败返回-1(小于0)。

所以,接收fork返回值的变量也是数据,但fork给子进程和父进程返回的值均不相同,所以这里也会发生一次写实拷贝。

0,子进程给父进程返回其pid值(大于0),创建失败返回-1(小于0)。

所以,接收fork返回值的变量也是数据,但fork给子进程和父进程返回的值均不相同,所以这里也会发生一次写实拷贝。

总结

1.子进程是由父进程的模板创建的
2.子进程和父进程一般情况下共享代码和数据,但如果有一方的数据或代码被修改,那么操作系统会写实拷贝一份。
3.fork函数不是真的有2个返回值,而是两个进程都在fork函数执行了返回操作。
4.fork返回父进程子进程的PID,给子进程返回0,进程创建失败返回-1

  • 71
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 61
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 61
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

林 子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值