进程控制1 (从进程创建到进程等待wait)

目录​​​​​​​

 一、进程创建

     1.1回顾fork:

1.2  fork内部完成的事情

1.3用户空间&内核空间

1.4  写实拷贝(重点) ​编辑

1.5  fork创建子进程的一些特性:

1.6  fork的一些用法

二、进程终止

2.1进程终止的场景

2.2 正常终止(可通过‘$?’查看进程退出码)

2.4 exit 和_exit的区别

2.5刷新缓冲区

2.6缓冲方式

三、进程等待

3.1进程等待的必要性

3.2wait函数

 3..3、wait函数中的退出状态信息

3.4wait怎么获取退出信号呢?

总结


  •  一、进程创建

  •      1.1回顾fork:

  • 让正在运行的进程创建出来一个子进程。它从已存在进程中创建一个新进 程。新进程为子进程,而原进程为父进程


  • 1.2  fork内部完成的事情


  • 1.3用户空间&内核空间

用户空间:程序猿自己写的代码都是在用户空间里运行的,但是会切换到内核空间去,(比如调用了系统调用函数fork),执行完毕后返回用户空间继续执行。

内核空间:系统调用的函数都是在内核空间运行的,因为是操作系统提供的函数

 


  • 1.4  写实拷贝(重点) 

父进程创建子进程,子进程的PCB拷贝父进程,页表也是拷贝父进程的。在最初的时候,同一个变量的虚拟地址和物理地址的映射关系是一样的,也就是说操作系统并没有给子进程当中的变量分配物理内存,子进程的变量还是原来父进程的物理内存的内容

发生改变时:才以写实拷贝的方式进行拷贝一份,此时父子进程通过各自的页表,指向不同的物理内存。

当不改变时:父子进程共享同一个数据。(这样省内存

结论:

1、每一个进程都有一个页表结构

2、fork创建出来的子进程,也会拷贝父进程的页表关系

3、写实拷贝是“懒汉思想”、“聪明思想”


  • 1.5  fork创建子进程的一些特性:

1、父子进程是独立运行的,互不干扰,各自有各自的进程虚拟空间

2、父子进程是抢占式运行,谁先谁后执行本质上是操作系统调度决定的(当然也和自身准备情况有关)

3.子进程是从fork之后开始进行的。(程序计数器+上下文指针)

4、代码共享,数据独有


  • 1.6  fork的一些用法

守护进程(重要)

         父进程创建子进程,让子进程执行真正的业务(进程程序替换),父进程负责守护子进程。

   当子进程在执行时意外“挂掉了”,父进程负责重新启动子进程。让子进程继续提供服务。(这样就可以保证了不需要人一直看着子进程

举个小例子:

对于QQ这个软件,聊天框就是一个子进程,QQ负责守护聊天的进程。很多程序其实比较简单,但维护起来才是最为困难的,就比如QQ用户几亿,怎样能保证每个聊天都正常进行就成了程序员的一个很重要的任务。

本质就是:提高程序“高可用”的一种手段


  • 二、进程终止

  • 2.1进程终止的场景

1、正常(相亲加VX成功)

      1.1、代码运行完毕,完成代码功能(约了看电影

      1.2、代码运行完毕,但没有完成既定的功能(没约上看电影,G

2、异常(相亲VX都没加上)


  • 2.2 正常终止(可通过‘$?’查看进程退出码)

1、从main函数的return返回2、调用exit函数(库函数)

 调用_exit函数(系统调用函数)

.3异常终止(直接G

1.解引用空指针,解引用野指针(垂悬指针)

会发生段错误

 2.double  free(c++字符浅拷贝)

3.内存访问越界

每个进程都有自己的虚拟进程空间,一旦越界就会去访问别的程序的虚拟空间,这时候一调用页表就会被操作系统检测出来,将其强杀


  • 2.4 exit 和_exit的区别

  • 1.exit函数比——exit多执行的两个步骤         
  • 1.执行用户自定义的清理函数        
  •     2.冲刷缓冲区,关闭流等

 exit函数:

1.执行用户自定义的清理函数

atexit函数:

当进程结束时才调用

 

可以看到,atexit是先于“helleo world ”的,单输出的情况确实hello world先输出,证明了atexit回调了

atexit_callback    被称为回调函数

  • 2.5刷新缓冲区

  • 何为刷新缓冲区?           (如图

刷新缓冲区的方式:

1、先来看_exit  函数

在没有\n的情况下,是打印不出来的,证明没有刷新缓冲区

      

 2、那要是变成exit会怎么样

能够看到是可以打印出来的,这就证明的exit确实刷新了缓冲区 

 3、fflush函数(向标准输出中刷新)。

4.加上\n 


  • 2.6缓冲方式

  • 三、进程等待

  • 3.1进程等待的必要性

父进程进行进程等待,等待子进程退出后,回收子进程的退出状态信息,防止子进程变成僵尸进程


  • 3.2wait函数

        wait函数的属性:阻塞(死等

                       ·~~~~~~    如何佐证wait的阻塞属性呢?·~~~~~~~~~ 

           使用pstack【pid】命令:能查看进程的调用堆栈,直白点就是可以查看进程正在运行什么代码

 

可以看到父进程是一直在等待着子进程


 3..3、wait函数中的退出状态信息

首先这个参数是int型,一共是四个字节 

但他的退出状态信息只用到了两个字节

 

  ~~~~~~~~ 怎样通过进程退出状态信息判断进程是正常退出还是异常退出

标准:    看推出信息是否有值

           *退出信号==0:正常终止   ===》此时才会有退出码(也可理解为此时退出码才生效

           *退出信号>0:异常终止   ===》即收到了退出信息,这时候才不为0

coredump:标志着是否产生核心转储文件                 


  • 3.4wait怎么获取退出信号呢?

(代码实现回头再编,感觉写完这篇博客头发掉了几十跟)


总结

总结了Linux中的从进程创建到进程等待(wait)。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值