Linux C 进程编程

进程编程

  • 进程介绍
    • 进程的定义
    • 进程和线程以及程序的区别
    • 进程块PCB
      • 进程的状态
      • 相关指令
    • 进程调度算法
      • 先来先服务调度算法 FCFS
      • 短作业(进程)优先调度算法 SJF
      • 优先权调度算法 FPF
        • 优先权调度算法的类型
          • 非抢占式优先权算法
          • 抢占式优先权算法
        • 优先权类型
          • 静态优先权
          • 动态优先权
        • 高响应比优先调度算法
      • 基于时间片的轮转调度算法
    • 进程的状态
    • 相关函数
      • fork  创建子进程
      • vfork  创建子进程
      • system  Shell命令创建子进程
      • execl  创建子进程
      • 四个创建子进程函数的区别
      • 进程的退出
    • 进程退出产生的相关问题
      • 孤儿进程
      • 僵尸进程
      • 下面提供了一些解决措施
  • 参考文献

进程介绍

进程的定义

  官方的来说,进程是程序在某个数据集合上的一次运行活动,也是操作系统进行资源分配和保护的基本单位。
  通俗的讲,进程就是在程序编译之后,运行起来的二进制文件。

进程和线程以及程序的区别

  程序是存储在磁盘上的可执行文件,是一组指令的集合,它是静态的,而进程包含了程序的代码和程序运行时所需的资源,如内存、文件描述符等。每个进程都是独立的,有自己的地址空间和资源,进程之间是相互独立的。线程则是进程中的执行单元,一个进程可以包含多个线程,这些线程共享进程的资源,包括内存和文件描述符。线程之间可以共享数据,并且可以更高效地进行通信和同步。
  因此,进程和线程都是程序的执行实例,它们之间的区别在于资源的独立性和共享性。程序是静态的代码和数据的集合,只有在运行时才会成为进程或线程。

进程块PCB

  进程控制块 (PCB)是系统为了管理进程设置的一个专门的数据结构。 系统用它来记录进程的外部特征,描述进程的运动变化过程。 同时,系统可以利用PCB来控制和管理进程,所以说,PCB(进程控制块)是系统感知进程存在的唯一标志。
  Linux中可以使用 “ps auxjf” 指令查看进程的静态信息,使用 “top” 指令查看进程的动态信息。

字母解释
a现在一个终端的所有进程
u显示进程的归属用户以及内存使用情况
x显示出和终端没有关联的进程
j显示进程归属的进程组id,会话id,父进程id
f以ascii形式显示出进程的层次关系

进程的状态

在这里插入图片描述

状态状态属性
R:执行状态<:优先级高的进程,比优先级的进程运行的次数更频繁。
S:休眠状态N:低优先级的进程
Z:僵尸进程s:包含子进程
T:停止状态I:位于后台的进程组
D:无法中断的休眠状态+:进程组内的前台进程

相关指令

1) 进程运行切换
  ① 在终端后台运行一个进程:./ 可执行命令 空格 &
  ② 查看终端的后台进程:jobs
  ③ 让进程n到后台去:bg %n
  ④ 让后台运行的进程n到前台来:fg %n
  ⑤ 把前台进程已停止状态进入后台进程:ctrl + z。
  注:一个终端只能有一个前台进程,剩余的所有进程都是后台进程。
2) 杀死进程:kill 空格 参数 空格 杀死的目标(进程 ID),常用参数为-9。

进程调度算法

  这里只做简单介绍,具体和算法部分可以自行单独搜索。

先来先服务调度算法 FCFS

  先来先服务(FCFS)调度算法是一种最简单的调度算法,该算法既可用于作业调度,也可用于进程调度。当在作业调度中采用该算法时,每次调度都是从后备作业队列中选择一个或多个最先进入该队列的作业,将它们调入内存,为它们分配资源、创建进程,然后放入就绪队列。在进程调度中采用 FCFS 算法时,则每次调度是从就绪队列中选择一个最先进入该队列的进程,为之分配处理机,使之投入运行。该进程一直运行到完成或发生某事件而阻塞后才放弃处理机。
  FCFS 算法比较有利于长作业(进程),而不利于短作业(进程)。

短作业(进程)优先调度算法 SJF

  短作业(进程)优先调度算法 SJ§F,是指对短作业或短进程优先调度的算法。它们可以分别用于作业调度和进程调度。短作业优先(SJF)的调度算法是从后备队列中选择一个或若干个估计运行时间最短的作业,将它们调入内存运行。而短进程优先(SPF)调度算法则是从就绪队列中选出一个估计运行时间最短的进程,将处理机分配给它,使它立即执行并一直执行到完成,或发生某事件而被阻塞放弃处理机时再重新调度。
  SJF 调度算法能有效地降低作业的平均等待时间,提高系统吞吐量。但是该算法对长作业不利,并且不能保证紧迫性作业(进程)会被及时处理。

优先权调度算法 FPF

优先权调度算法的类型

  为了照顾紧迫型作业,使之在进入系统后便获得优先处理,引入了最高优先权优先(FPF)调度算法。此算法常被用于批处理系统中,作为作业调度算法,也作为多种操作系统中的进程调度算法,还可用于实时系统中。当把该算法用于作业调度时,系统将从后备队列中选择若干个优先权最高的作业装入内存。当用于进程调度时,该算法是把处理机分配给就绪队列中优先权最高的进程,这时,又可进一步把该算法分成如下两种。

非抢占式优先权算法

  在这种方式下,系统一旦把处理机分配给就绪队列中优先权最高的进程后,该进程便一直执行下去,直至完成;或因发生某事件使该进程放弃处理机时,系统方可再将处理机重新分配给另一优先权最高的进程。
  这种调度算法主要用于批处理系统中;也可用于某些对实时性要求不严的实时系统中。

抢占式优先权算法

  在这种方式下,系统同样是把处理机分配给优先权最高的进程,使之执行。但在其执行期间,只要又出现了另一个其优先权更高的进程,进程调度程序就立即停止当前进程(原优先权最高的进程)的执行,重新将处理机分配给新到的优先权最高的进程。因此,在采用这种调度算法时,是每当系统中出现一个新的就绪进程 i 时,就将其优先权 Pi 与正在执行的进程 j 的优先权 Pj 进行比较。如果 Pi≤Pj,原进程 Pj 便继续执行;但如果是 Pi>Pj,则立即停止 Pj 的执行,做进程切换,使 i 进程投入执行。
  显然,这种抢占式的优先权调度算法能更好地满足紧迫作业的要求,故而常用于要求比较严格的实时系统中,以及对性能要求较高的批处理和分时系统中。

优先权类型

  对于最高优先权优先调度算法,其关键在于:它是使用静态优先权,还是用动态优先权,以及如何确定进程的优先权。

静态优先权

  静态优先权是在创建进程时确定的,且在进程的整个运行期间保持不变。一般地,优先权是利用某一范围内的一个整数来表示的,例如,0~7 或 0~255 中的某一整数,又把该整数称为优先数,只是具体用法各异:有的系统用“0”表示最高优先权,当数值愈大时,其优先权愈低;而有的系统恰恰相反。
  确定进程优先权的依据有如下三个方面:进程类型、进程对资源的需求、用户要求。

动态优先权

  动态优先权是指在创建进程时所赋予的优先权,是可以随进程的推进或随其等待时间的增加而改变的,以便获得更好的调度性能。例如,我们可以规定,在就绪队列中的进程,随其等待时间的增长,其优先权以速率 a 提高。若所有的进程都具有相同的优先权初值,则显然是最先进入就绪队列的进程将因其动态优先权变得最高而优先获得处理机,此即FCFS 算法。若所有的就绪进程具有各不相同的优先权初值,那么,对于优先权初值低的进程,在等待了足够的时间后,其优先权便可能升为最高,从而可以获得处理机。当采用抢占式优先权调度算法时,如果再规定当前进程的优先权以速率 b 下降,则可防止一个长作业长期地垄断处理机。

高响应比优先调度算法

  在批处理系统中,短作业优先算法是一种比较好的算法,其主要的不足之处是长作业的运行得不到保证。如果我们能为每个作业引入前面所述的动态优先权,并使作业的优先级随着等待时间的增加而以速率 a 提高,则长作业在等待一定的时间后,必然有机会分配到处理机。该优先权的变化规律可描述为:

优先权 = 等待时间  + 要求服务时间  要求服务时间  =\frac{\text { 等待时间 }+ \text { 要求服务时间 }}{\text { 要求服务时间 }} = 要求服务时间  等待时间 + 要求服务时间 

  由于等待时间与服务时间之和就是系统对该作业的响应时间,故该优先权又相当于响应比 RP。据此,又可表示为:

R P = 等待时间  + 要求服务时间  要求服务时间  = 响应时间  要求服务时间  R_{\mathrm{P}}=\frac{\text { 等待时间 }+ \text { 要求服务时间 }}{\text { 要求服务时间 }}=\frac{\text { 响应时间 }}{\text { 要求服务时间 }} RP= 要求服务时间  等待时间 + 要求服务时间 = 要求服务时间  响应时间 

基于时间片的轮转调度算法

  如前所述,在分时系统中,为保证能及时响应用户的请求,必须采用基于时间片的轮转式进程调度算法。在早期,分时系统中采用的是简单的时间片轮转法;进入 20 世纪 90年代后,广泛采用多级反馈队列调度算法。

进程的状态

1 ) 就绪(Ready)状态
  当进程已分配到除 CPU 以外的所有必要资源后,只要再获得 CPU,便可立即执行,进程这时的状态称为就绪状态。在一个系统中处于就绪状态的进程可能有多个,通常将它们排成一个队列,称为就绪队列。
2 ) 执行状态
  进程已获得 CPU,其程序正在执行。在单处理机系统中,只有一个进程处于执行状态;在多处理机系统中,则有多个进程处于执行状态。
3 ) 阻塞状态
  正在执行的进程由于发生某事件而暂时无法继续执行时,便放弃处理机而处于暂停状态,亦即进程的执行受到阻塞,把这种暂停状态称为阻塞状态,有时也称为等待状态或封锁状态。致使进程阻塞的典型事件有:请求 I/O,申请缓冲空间等。通常将这种处于阻塞状态的进程也排成一个队列。有的系统则根据阻塞原因的不同而把处于阻塞状态的进程排成多个队列。

在这里插入图片描述

相关函数

fork  创建子进程

头文件:
   #include<unistd.h>
函数原型::pid_t fork(void);
函数介绍:fork()会产生一个新的子进程,其子进程会复制父进程的数据与堆栈空间,并继承父进程的用户代码,组代码,环境变量、已打开的文件代码、工作目录和资源限制等。父子之间抢占CPU执行。
返回值:如果 fork()成功则在父进程会返回新建立的子进程代码(PID),而在新建立的子进程中则返回 0。如果 fork 失败则直
接返回-1,失败原因存于 errno 中。

	pid_t pid = fork();

vfork  创建子进程

头文件:
  #include<unistd.h>
函数原型::pid_t vfork(void);
函数介绍: vfork()会产生一个新的子进程,其子进程会复制父进程的数据与堆栈空间,并继承父进程的用户代码,组代码,环境变量、已打开的文件代码、工作目录和资源限制等。数据空间与父进程共享(全局变量区 文本常量区)。先运行子进程,子进程结束后再运行父进程。
返回值:如果 vfork()成功则在父进程会返回新建立的子进程代码(PID),而在新建立的子进程中则返回 0。如果 fork 失败则
直接返回-1,失败原因存于 errno 中。

	pid_t pid = vfork();

system  Shell命令创建子进程

头文件:
  #include<stdlib.h>
函数原型:int system(const char * string);
参数介绍:
  string:可执行文件 路径+名字
函数介绍::system()会调用 fork()产生子进程,由子进程来调用/bin/sh-c string 来执行参数 string 字符串所代表的命令,此命令执行完后随即返回原调用的进程。在调用 system()期间 SIGCHLD 信号会被暂时搁置,SIGINT 和 SIGQUIT 信号则会被忽略。
返回值:如果 system()在调用/bin/sh 时失败则返回 127,其他失败原因返回-1。若参数 string 为空指针(NULL),则返回非零值。如果 system()调用成功则最后会返回执行 shell 命令后的返回值,但是此返回值也有可能为 system()调用/bin/sh 失败所返回的 127,因此最好能再检查 errno 来确认执行成功。

	system("./fun");

execl  创建子进程

头文件:
  #include<unistd.h>
函数原型:int execl(const char * path,const char * arg,…);
参数介绍:
  path:文件路径+名字
  arg:所要传送的参数,最后必须使用NULL作为结束
函数介绍:execl用另一个新程序替换了当前进程的正文、数据、堆和栈段,进程ID不变。
返回值:如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于 errno 中。

四个创建子进程函数的区别

函数复制父进程数据是否有自己的独立空间修改数据影响父进程是否创建新进程
fork
vfork
system
execl

进程的退出

  进程退出三种方法:return、exit()、_exit()。第二种为常用。
三者的区别:
return:
  在函数中使用return语句可以退出当前函数并返回一个值给调用者,但不会结束整个进程。
exit():
  exit()是一个库函数,用于正常终止当前进程,并返回一个状态码给操作系统。它会执行一系列清理工作,如关闭文件、释放内存等,然后终止进程。
_exit():
   _exit()是一个系统调用,用于立即终止当前进程,不会执行任何清理工作。它直接通知操作系统终止进程,不会触发任何终止处理程序,也不会刷新缓冲区或关闭文件。通常情况下,应该在使用fork()创建子进程后,使用_exit()来终止子进程。

进程退出产生的相关问题

孤儿进程

孤儿进程的本质上还是个普通的进程,是指一个父进程退出,而它的一个或者多个子进程还在运行,那么这些子进程就称为孤儿进程。孤儿进程会被系统指定的进程所收养,并由收养孤儿进程的进程对他们进程完成状态收集工作。注:在“红帽 Linux 系统”中,孤儿进程将被“init 进程(进程号为 1)”的进程所收养,但是在“乌班图 Linux系统中”,是由“upstart 进程”所收养。

僵尸进程

Linux 的进程在结束的时候不会对自己的资源进行清零,只有父进程结束时才会对子进程的资源进程清零。僵尸进程是指子进程先于父进程退出,父进程退出的时候没有回收子进程退出状态的资源(task_struct),因此子进程就称为僵尸进程(孩子寄了,父亲没有收s)。写程序时要尽量避免出现僵尸进程(系统垃圾),利用等待进程退出函数可以解决僵尸进程问题。

下面提供了一些解决措施

1)父进程使用wait()或waitpid()系统调用来回收子进程的资源,避免子进程成为僵尸进程。
2 )使用信号处理机制,在父进程中注册SIGCHLD信号处理函数,当子进程终止时会触发该信号,父进程可以在信号处理函数中回收子进程的资源。
3 )使用守护进程来创建子进程,守护进程会负责回收子进程的资源,避免子进程成为僵尸进程。

参考文献

文章 进程调度算法 和 进程状态 部分内容参考于 《计算机操作系统(第 三 版)》 汤小丹 梁红兵 哲凤屏 汤子瀛 编著
(想要资源的可以私信我,我有PDF版本)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/141985.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图论13-最小生成树-Kruskal算法+Prim算法

文章目录 1 最小生成树2 最小生成树Kruskal算法的实现2.1 算法思想2.2 算法实现2.2.1 如果图不联通&#xff0c;直接返回空&#xff0c;该图没有mst2.2.2 获得图中的所有边&#xff0c;并且进行排序2.2.2.1 Edge类要实现Comparable接口&#xff0c;并重写compareTo方法 2.2.3 取…

VR全景技术在城市园区发展中有哪些应用与帮助

引言&#xff1a; 在数字化时代的浪潮中&#xff0c;虚拟现实&#xff08;VR&#xff09;全景技术逐渐融入各个领域&#xff0c;也为城市园区展示带来了全新的可能性。 一&#xff0e;VR全景技术简介 虚拟现实全景技术是一种通过全景图像和视频模拟真实环境的技术。通过相关设…

【极客时间-系列教程】Vim 实用技巧必知必会-更多常用命令:应对稍复杂的编辑任务

文章目录 更多常用命令&#xff1a;应对稍复杂的编辑任务光标移动文本修改文本对象选择 更多常用命令&#xff1a;应对稍复杂的编辑任务 几个基本的命令已经了解了&#xff0c;可以操作简单的任务&#xff0c;但一些很复杂的命令&#xff0c;并没有了解到&#xff0c;只知道几…

每天一点python——day67

#每天一点Python——67 #字符串判断方法&#xff1a;如图&#xff1a; #①判断指定字符串是否为合法标识符 shello,computer print(s.isidentifier()) #输出为False&#xff0c;不是合法标识符&#xff0c;这是因为标识符是由字母&#xff0c;数字&#xff0c;下划线组成&#…

【C++】new和delete深度解析

文章目录 一、new/delete是什么&#xff1f;1.new2.delete 二、new/delete怎么用&#xff1f;1.new2.delete3.new[]4.[]delete 三、new/delete为什么&#xff1f;1.为什么有operator new/operator delete?2.为什么要匹配使用new和delete? new/delete测试环境&#xff1a;visu…

线性代数本质系列(二)矩阵乘法与复合线性变换,行列式,三维空间线性变换

本系列文章将从下面不同角度解析线性代数的本质&#xff0c;本文是本系列第二篇 向量究竟是什么&#xff1f; 向量的线性组合&#xff0c;基与线性相关 矩阵与线性相关 矩阵乘法与复合线性变换 三维空间中的线性变换 行列式 逆矩阵&#xff0c;列空间&#xff0c;秩与零空间 克…

海上船舶交通事故VR模拟体验低成本高效率-深圳华锐视点

在海上运输行业&#xff0c;安全事故的防范和应对能力是企业安全教育的重中之重。针对这一问题&#xff0c;海上运输事故VR模拟逃生演练成为了一种创新且高效的教育手段。通过这种演练&#xff0c;企业能够在提升员工安全意识和技能方面获得多方面的帮助。 在VR船舶搜救演练中&…

基于RFbeam的V-LD1-60GHz毫米波雷达传感器数据获取(通过UART串口来控制模块)

基于RFbeam的V-LD1-60GHz毫米波雷达传感器数据获取&#xff08;通过UART串口来控制模块&#xff09; 文章目录 V-LD1命令发送消息回复通信示例雷达数据获取宏定义通信代码运行效果附录&#xff1a;压缩字符串、大小端格式转换压缩字符串浮点数压缩Packed-ASCII字符串 大小端转…

【广州华锐视点】海外制片人VR虚拟情景教学带来全新的学习体验

虚拟现实&#xff08;Virtual Reality&#xff0c;简称VR&#xff09;是一种利用电脑模拟产生一个三维的虚拟世界&#xff0c;提供用户关于视觉、听觉、触觉等感官的模拟体验的技术。随着科技的进步&#xff0c;VR已经被广泛应用到许多领域&#xff0c;包括游戏、教育、医疗、房…

K8S容器持续Terminating无法正常关闭(sider-car容器异常,微服务容器正常)

问题 K8S上出现大量持续terminating的Pod&#xff0c;无法通过常规命令删除。需要编写脚本批量强制删除持续temminating的Pod&#xff1a;contribution-xxxxxxx。 解决 获取terminating状态的pod名称的命令&#xff1a; # 获取media命名空间下&#xff0c;名称带contributi…

通过docker-compose部署elk日志系统,并使用springboot整合

ELK是一种强大的分布式日志管理解决方案&#xff0c;它由三个核心组件组成&#xff1a; Elasticsearch&#xff1a;作为分布式搜索和分析引擎&#xff0c;Elasticsearch能够快速地存储、搜索和分析大量的日志数据&#xff0c;帮助用户轻松地找到所需的信息。 Logstash&#xf…

深度学习之基于Pytorch服装图像分类识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介系统组成1. 数据集准备2. 数据预处理3. 模型构建4. 模型训练5. 模型评估 PyTorch的优势 二、功能三、系统四. 总结 一项目简介 深度学习在计算机视觉领域的…

软件测试自学指南,十年阿里测试工程师的建议

通过技能提升&#xff0c;入行IT可以的&#xff0c;但得先积累足够的经验&#xff0c;才能拿高薪&#xff0c;有个成长的过程。 软件测试岗介绍 软件测试岗位主要负责系统的测试工作&#xff0c;属于IT项目中的质量管理&#xff08;QA&#xff09;模块。 这个岗位分为两种类…

Adobe研究人员研发新AI模型LRM:实现从2D样本瞬时生成3D图像

由Adobe Research和澳大利亚国立大学&#xff08;ANU&#xff09;联合研发的人工智能模型宣布了一项突破性的成果&#xff0c;能够从单一的2D图像中生成3D图像。 研究人员表示&#xff0c;他们的新算法在大规模图像样本上进行训练&#xff0c;可以在几秒钟内生成这样的3D图像。…

【LIUNX】配置缓存DNS服务

配置缓存DNS服务 A.安装bind bind-utils1.尝试修改named.conf配置文件2.测试nslookup B.修改named.conf配置文件1.配置文件2.再次测试 缓存DNS服务器&#xff1a;只提供域名解析结果的缓存功能&#xff0c;目的在于提高数据查询速度和效率&#xff0c;但是没有自己控制的区域地…

阿里云国际站:应用实时监控服务

文章目录 一、阿里云应用实时监控服务的概念 二、阿里云应用实时监控服务的优势 三、阿里云应用实时监控服务的功能 四、写在最后 一、阿里云应用实时监控服务的概念 应用实时监控服务 (Application Real-Time Monitoring Service) 作为一款云原生可观测产品平台&#xff…

记忆科技携手中国电信,一站式存储打造坚实数字底座

11月10日&#xff0c;以“数字科技 焕新启航”为主题的2023数字科技生态大会在广州盛大开幕&#xff0c;本次大会由中国电信、广东省人民政府联合举办&#xff0c;是一场数字科技领域的年度盛会。忆联母公司记忆科技作为中国电信的合作伙伴之一受邀参会&#xff0c;深度参与了大…

Flink SQL -- 命令行的使用

1、启动Flink SQL 首先启动Flink的集群&#xff0c;选择独立集群模式或者是session的模式。此处选择是时session的模式&#xff1a;yarn-session.sh -d 在启动Flink SQL的client&#xff1a; sql-client.sh 2、kafka SQL 连接器 在使用kafka作为数据源的时候需要上传jar包到…

LabVIEW中NIGPIB设备与驱动程序不相关的MAX报错

LabVIEW中NIGPIB设备与驱动程序不相关的MAX报错 当插入GPIB-USB设备时&#xff0c;看到了NI MAX中列出该设备&#xff0c;但却显示了黄色警告指示&#xff0c;并且指出Windows没有与您的设备相关的驱动程序。 解决方案 需要安装能兼容的NI-488.2驱动程序。 通过交叉参考以下有…

【C++初阶(八)】C/C++内存管理详解

本专栏内容为&#xff1a;C学习专栏&#xff0c;分为初阶和进阶两部分。 通过本专栏的深入学习&#xff0c;你可以了解并掌握C。 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;C &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&…