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版本)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

接口测试--知识问答

1 做接口测试当请求参数多时tps下降明显&#xff0c;此接口根据参数从redis中获取数据&#xff0c;每个参数与redis交互一次&#xff0c;当一组参数是tps5133&#xff0c;五组参数是tps1169&#xff0c;多次交互影响了处理性能&#xff0c;请详细阐述如何改进增进效果的方案。 …

酷柚易汛ERP - 序列号状态表操作指南

1、应用场景 序列表状态表统计商品的每个序列号目前的状态&#xff08;在库、已出库&#xff09;&#xff0c;每个序列号仅会显示一条记录。 2、主要操作 打开【仓库】-【序列号状态表】&#xff0c;可勾选序列号在库/已出库两种状态查询&#xff0c;其它筛选操作与上文其它…

垃圾/垃圾桶识别相关开源数据集汇总

垃圾箱图片数据集 数据集下载链接&#xff1a;http://suo.nz/3cvbiC 垃圾箱多类检测数据集 数据集下载链接&#xff1a;http://suo.nz/2eluH3 蒙得维亚的垃圾箱图片 数据集下载链接&#xff1a;http://suo.nz/2lRHLK 垃圾桶满溢检测数据集 数据集下载链接&#xff1a;http:…

【HttpRunner】接口自动化测试框架

简介 2018年python开发者大会上&#xff0c;了解到HttpRuuner开源自动化测试框架&#xff0c;采用YAML/JSON格式管理用例&#xff0c;能录制和转换生成用例功能&#xff0c;充分做到用例与测试代码分离&#xff0c;相比excel维护测试场景数据更加简洁。在此&#xff0c;利用业余…

filte(过滤数组)

根据条件&#xff0c;保留满足条件的对应项&#xff0c;得到一个新数组

关于我在配置zookeeper出现,启动成功,进程存在,但是查看状态却没有出现Mode:xxxxx的问题和我的解决方案

在我输入:zkServer.sh status 之后出现报错码. 报错码&#xff1a; ZooKeeper JMX enabled by default Using config: /opt/software/zookeeper/bin/../conf/zoo.cfgClient port found: 2181. Client address: localhost. Error contacting service. It is probably not runni…

11.读取文件长度-fseek和ftell函数的使用

文章目录 简介1. 写入测试文件2. 读取文件长度 简介 主要讲使用fopen读取文件&#xff0c;配合使用fseek和ftell来读取文件长度。1. 写入测试文件 执行下方程序&#xff0c;使用fwrite函数写入40字节的数据&#xff0c;使其形成文件存入本地目录。#define _CRT_SECURE_NO_WARNI…

【SpringBoot】SpringBoot自动配置底层源码解析

概述 EnableAutoConfiguration源码解析SpringBoot常用条件注解源码解析SpringBoot之Mybatis自动配置源码解析SpringBoot之AOP自动配置源码解析SpringBoot Jar包启动过程源码解析 DeferredImportSelector接口 DeferredImportSelector和ImportSelector的区别在于&#xff1a; …

Leetcode—202.快乐数【简单】

2023每日刷题&#xff08;二十八&#xff09; Leetcode—202.快乐数 快慢指针思想 通过手玩2&#xff0c;可以发现 会走入一个循环&#xff0c;并且fast和slow会在一个数字相遇&#xff0c;以下也大概花了一下推倒出来了。如果slow不是因为1和fast相等的&#xff0c;就说明它…

Nginx的安装

Nginx的安装 Windows下Nginx的安装 1、下载nginx 下载稳定版本: http://nginx.org/en/download.html 直接下载 nginx-1.20.0.zip : http://nginx.org/download/nginx-1.20.0.zip 下载后解压&#xff0c;解压后如下&#xff1a; 2、启动Nginx 有很多种方法启动nginx (…

如何准确分析需求

业务驱动的需求思想 要做好软件需求工作&#xff0c;业务驱动需求思想是核心。传统的需求分析是站在技术视角展开的&#xff0c;关注的是“方案级需求”&#xff1b;而业务驱动的需求思想则是站在用户视角展开的&#xff0c;关注的是“问题级需求”。 变更/优化型需求分析任务…

视频监控系统EasyCVR平台播放告警录像时,播放器显示不全是什么原因?

防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安防…

Python高级语法----Python类型注解与类型检查

文章目录 一、类型注解基础二、使用 `mypy` 进行类型检查三、类型注解的最佳实践结论在当今的软件开发实践中,类型注解和类型检查在提高代码的可读性和健壮性方面发挥着至关重要的作用。尤其在 Python 这种动态类型语言中,通过类型注解和类型检查工具,如 mypy,可以显著提升…

Git系列之分支与标签的使用及应用场景模拟

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是君易--鑨&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的博客专栏《Git实战开发》。&#x1f3af;&#x1f3af; &a…

语音识别芯片在产品应用上的难点列举

语音识别技术&#xff0c;作为人工智能领域中的一颗璀璨明珠&#xff0c;已经广泛应用于用户交互、智能家居、语音助手等多个领域。它为我们的生活带来了诸多便利&#xff0c;使得我们可以更加高效地与电子设备进行互动。然而&#xff0c;语音识别技术的实现&#xff0c;依赖于…

LEEDCODE 75颜色分类

耍赖皮写法 嘻嘻 class Solution { public:void sortColors(vector<int>& nums) {int count1 0;int count2 0;int count3 0;for(int i 0; i<nums.size(); i){if(nums[i] 0)count1 1;else if(nums[i] 1)count2 1;else count3 1;}for(int i 0; i<nu…

缅因州政府通知130万人MOVEit数据泄露事件

大家好&#xff0c;今天我要向大家通报一个令人震惊的消息&#xff1a;缅因州政府的系统遭到了入侵&#xff0c;黑客利用MOVEit文件传输工具的漏洞&#xff0c;获取了约130万人的个人信息&#xff0c;这几乎相当于该州的整个人口数量。 MOVEit攻击是Clop勒索软件团伙进行的一次…

前端---CSS的盒模型

文章目录 什么是盒模型&#xff1f;设置边框设置内边距设置外边距块级元素水平居中 什么是盒模型&#xff1f; 页面上的每个HTML元素都是一个一个的“盒子”&#xff0c;这些盒子由&#xff1a;内容、内边距、边框、外边距组成。 我们可以和住的房子联系起来&#xff0c;更好…

找工作的网站都有哪些

吉鹿力招聘网作为一家知名的招聘网站&#xff0c;因其功能完善和用户隐私保护而备受用户青睐。它不仅可以与企业直接沟通&#xff0c;还可以提供在线聊工作的机会。通过吉鹿力招聘网&#xff0c;用户可以自主选择工作地点、时间和工作类型&#xff0c;大大提高了找到合适工作的…