Linux|进程控制

进程创建

fork函数初识

在linux中fork函数时非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。
返回值:子进程中返回0,父进程返回子进程id,出错返回-1
进程调用fork,当控制转移到内核中的fork代码后,内核做:

  • 分配新的内存块和内核数据结构(task_struct,mm_struct,页表等)给子进程
  • 将父进程部分数据结构内容拷贝至子进程
  • 添加子进程到系统进程列表当中
  • fork返回,开始调度器调度
    当一个进程调用fork之后,就有两个二进制代码相同的进程。而且它们都运行到相同的地方。但每个进程都将可以

当一个进程调用fork之后,就有两个二进制代码相同的进程。而且它们都运行到相同的地方。但每个进程都将可以开始它们自己的旅程

进程 = 1内核数据结构+2代码和数据
fork创建子进程的时候 是先1还是2呢?
答案是1举个例子我们去大学报名,是档案先去人后面再去

写时拷贝

通常,父子代码共享,但是数据不是是共享的,当任意一方试图写入,便以写时拷贝的方式各自一份副本。

fork调用失败的原因

系统中有太多的进程
实际用户的进程超过了限制

进程终止

想明白:终止在做什么?

  • 释放代码,数据(本身就不再被调度了)和内核数据结构
  • 但是task_struct 这个内核数据结构会被延期释放,因为要返回子进程的退出信息

进程终止的情况

进程终止的情况有三种

  • 代码跑完结果正确
  • 代码跑完结果不正确
  • 异常退出
main函数的返回值

main函数的返回值,我们称为退出码,关心方要知道进程指向情况怎么。
我们可以通过ehco $?来查看最近一个进程的退出码
对于一个进程来讲 0代表成功 非0表示失败,因为成功我们就不管了,但是失败了要知道是什么情况。刚好非零的数字特别多
在这里插入图片描述
在这里插入图片描述
退出码含义:
在这里插入图片描述
bash获取最近一个进程的退出码,要知道进程的执行情况怎么样?为用户负责。

自定义退出码

在这里插入图片描述

异常退出

比如说我们解引用空指针写入数据,会发生segmentation fault(段错误)
在这里插入图片描述
在这里插入图片描述
其实本质是操作系统给进程了一个信号
我举个例子证明,下面这个代码正常情况会一直运行
在这里插入图片描述
但是我们给它一个信号他就会报段错误
在这里插入图片描述
异常的时候我们看退出信号是什么就可以判断出是什么异常了

衡量一个进程退出只需要两个数字一个退出码另一个退出信号

如何终止进程

  • main函数return 表示进程终止
  • 代码任意位置调用_exit(),exit()函数表示进程终止

_exit() 和 exit()的区别

exit()退出的时候会刷新缓冲区而_exit()不会
在这里插入图片描述
在这里插入图片描述
用_exit()的结果
在这里插入图片描述
我们可以得出一个结论缓冲区一定不在操作系统内部,因为_exit()刷新不了缓冲区
在这里插入图片描述

进程等待

任何子进程在退出的情况下,一般必须有父进程进行等待。
为什么呢?

  • 父进程通过等待解决子进程退出的僵尸问题,回收系统资源
  • 获取子进程的退出信息

进程等待的操作

wait

  • wait 父进程等待任意一个进程
    在这里插入图片描述

staus 可以得到进程的退出码和退出信号,前16位没用
后16位开始 0~7位是退出码 第8位没用 ,9~15是退出信号
对于退出码我们只需要 status右移8位 退出码只需要 按位与0x7f(二进制01111 1111)
在这里插入图片描述

WIFEXITED(status): 查看是否正常退出

若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)

WEXITSTATUS(status): 查看退出码的宏

上面位操作得到退出码 还是有点麻烦,我们可以利用系统给的宏WEXITSTATUS得到退出码
在这里插入图片描述
在这里插入图片描述

waitpid

在这里插入图片描述
waitpid 的作用是等待子进程,
参数

  • pid:pid = -1时等待任意一个进程,其他就是等待指定的一个进程
  • stat_loc 用于保存退出码和退出信号,我们不关心退出码和退出信号的时候可以把它设置为0
  • options 用于选择父进程是阻塞等待还是非阻塞等待。WNOHANG时是非阻塞等待其他是0

返回值

  • ret > 0: 检查成功
  • ret = 0: 检查成功,但子进程还在运行
  • ret< 0: 等待失败

非阻塞等待就是父进程等待的过程,可以干其他事情

非阻塞等待的例子:

在这里插入图片描述

进程替换

进程替换的函数

这些函数的参数是什么·等下再介绍,我们先来看一个现象
在这里插入图片描述

现象

我们发现运行了ls命令 之后没有运行printf了,类似于被夺舍了
在这里插入图片描述
在这里插入图片描述

原理

将进程中的代码和数据完全替换,没有创建新进程哦,
本质就是进程被加载到内存了
在这里插入图片描述

多进程版

对于单一的一个进程,进程替换了原来这个进程就直接没了,大部分场景的时候我们都不希望这样做。
本质是对代码发生了写时拷贝

execl 这些接口的参数

在这里插入图片描述

  • path:告诉要执行的文件在什么位置
  • arg*… 是可变参数,他的参数个数可以不固定,命令行怎么写就怎么传
  • 在这里插入图片描述
  • 在这里插入图片描述
    在这里插入图片描述
    带p的可以不用传文件路径了,直接在环境变量中找

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-05-16 10:58:10       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-16 10:58:10       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-16 10:58:10       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-16 10:58:10       20 阅读

热门阅读

  1. 记录一下-排查免密登录过程

    2024-05-16 10:58:10       12 阅读
  2. Oracle如何实现rsa加密和例子

    2024-05-16 10:58:10       11 阅读
  3. GPT3.5与GPT4.0的差别对比

    2024-05-16 10:58:10       13 阅读
  4. 让调用者自己干活的特殊线程池

    2024-05-16 10:58:10       12 阅读
  5. Scala学习3: 字符串

    2024-05-16 10:58:10       13 阅读
  6. 教你拥有一个优雅的 Controller

    2024-05-16 10:58:10       13 阅读
  7. 【分布式】zookeeper遇到问题与解决

    2024-05-16 10:58:10       13 阅读
  8. Kotlin高阶函数用法之一

    2024-05-16 10:58:10       11 阅读