linux高级系统编程之进程

news2024/11/29 22:00:32

进程

一个正在进行的程序

并行与并发

并行:执行的程序在不同CPU上同时执行

并发:一个CPU,多个进程交替执行,因为交替速度很快,所以从宏观上来看是同时执行的,但是从围观的角度是交替执行的

单道与多道

单道程序设计:所有进程一个一个排队执行,若A阻塞,B只能等待,,即使CPU处于空闲状态

多道程序设计:在计算机内存中同时存放几道相互独立的程序,它们在管理程序控制之下,相互穿插的运行

进程控制块(PCB)

进程运行时,内核为每个进程分配一个PCB(进程控制块),维护进程相关的信息,linux内核的进程控制块是task_struct结构体

task_struct结构体

/usr/src/linux-headers-xxx/include/linux/sched.h 文件中可以查看
task_struct 结构体定义

其内部成员有很多
如:
        进程id:语言使用pid_t的类型表示,其实就是一个非负整数
        进程的状态:有就绪,运行,挂起,停止等状态
PCB存储位置
在内核中
                

进程号

当前进程的id就是进程号,由系统分配

每个进程都由一个进程号来标识,其类型为pid_t,进程号的范围:0~32767

进程号总是唯一的,但进程号可以重用,当一个进程终止后,其进程号就可以再次使用了

进程号为0和1的进程由内核创建

进程号为0的进程通常是调度进程,常被称为交换进程,进程号为1的进程通常是init进程

除调度进程(0号进程)外,在linux下面所有的进程都是由init(1号进程)进程直接或间接创建的

进程号(PID)

        标识进程一个非负整型数

        对应函数:

                pid_t getpid()        获取当前进程的进程号

进程组号(PGID)

        多个进程在同一个组中,该组就是进程组

        该组中第一个进程为组长进程,该组长进程的进程id就是该进程组id

        由进程A开启的子进程默认进程A为同组进程,此时A就是组长进程

        对应函数;

                pid_t getpgid(int pid)         获取指定进程所在的进程组号

父进程号(PPID)

        由进程A开启进程B,此时进程A就是进程B的父进程,进程B就是进程A的子进程

        对应函数:

                pid_t getppid()        获取当前进程的父进程号

                当进程A比进程B先销毁时,此时进程B就是孤儿进程,由1进程充当其父进程        

 扩展

命令:ps

作用:查看进程状态

参数:

        -a 显示终端上的所有进程,包括其他用户的进程

        -u 显示进程的详细状态

        -x 显示没有控制终端的进程

        -w 显示加宽,以便显示更多的信息

        -r 只显示正在运行的进程

        

        ps -aux:显示当前用户在运行到的进程信息

        ps -ajx:显示正在运行的相关联进程信息(包含父进程id(ppid),组id(pdid))

显示信息中STAT参数含义

        D 不可中断 Uninterruptibleusually IO

        R 正在运行,或在队列中的进程
        S(大写 ) 处于休眠状态
        T 停止或被追踪
        Z 僵尸进程
        W 进入内存交换(从内核 2.6 开始无效)
        X 死掉的进程
        < 高优先级
        N 低优先级
        s 包含子进程
        l 表示线程加锁
        + 位于前台的进程组

fork函数

作用:创建进程

语法:

        pid_t fork();

返回值:

        如果在子进程中就是0,如果在父进程中就是创建的子进程id,-1创建失败

        fork失败的两个主要原因是;

                1)当前的进程数已经达到了系统规定的上限,这时errno的值被设置为EAGAIN

                2)系统内存不足,这时errno的值被设置为ENOM

注意:

        1,子进程会从fork函数后开始执行

        2,子进程共享父进程所有内容,不包括进程号,父进程号等

                使用fork函数得到的子进程是父进程的一个复制品,它从父进程处继承了整个进程的地址空间

                 地址空间:包括进程上下文,进程堆栈,打开的文件描述符,信号控制设定,进程优先级,进程组号等

                子进程所独有的只有它的进程号,计时器等

                此外,使用fork函数的代价是很大的

        3,谁创建谁回收

进程状态

三状态:就绪态  执行态 等待态

五状态:新建态 终止态 运行态 就绪态 阻塞态

注意:

        阻塞态在其他语言中进行细分又可以分为阻塞态与休眠态

        休眠态又可以分为有限期休眠与无限期休眠

        休眠状态下不会抢夺CPU执行权

进程资源的回收

每个进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存资源等,但是任然为其保留一定的信息,这些信息主要指的是进程控制块的信息(包括进程号,退出状态,运行时间等);

回收原则:谁创建谁回收(父进程回收子进程资源)

wait函数

作用:回收进程资源

头文件:

        #include <sys/types.h>

        #include <sys/wait.h>

语法:

        pid_t wait(int *status);//阻塞

功能:

        等待任意一个子进程结束,如果任意一个子进程结束了,此函数会回收该子进程的资源

参数:

        status:进程退出时的状态信息

返回值:

        成功:已经结束子进程的进程号

        失败:-1

注意:

        1,会阻塞当前进程,知道回收一个子进程

        2,因为谁创建谁回收的原则,所以该函数在父进程中调用

exit函数与_exit函数

作用:退出当前进程

exit函数与_exit函数的区别?

exit函数属于库函数,_exit函数属于系统调用

exit函数所需头文件#include<stdlib.h>,_exit函数所需头文件#include<unistd.h>

exit函数为 void exit(int status) ,_exit函数 void -exit(int status);

两者参数一致:

        退出状态,0,正常退出,非0异常退出

注意:

        退出状态码取值区间:0~255

WIFEXITED(status)与WEXITSTATUS(status)

作用:

        WIFEXITED:获取进程退出时状态

        WEXITSTSTUS:获取进程退出时状态码

语法:

        WIFEXITED(status)

        WEXITSTATUS(status)

waitpid函数

作用:回收进程

头文件:

        #include<sys/types.h>

        #include<sys/wait.h>

语法:

        pid_t waitpid(pid_t pid,int *status,int options);

功能:

        等待子进程终止,如果子进程终止了,此函数会回收子进程的资源

参数:

       pid: 参数 pid 的值有以下几种类型:

                pid>0 等待进程ID等于pid的子进程

                pid=0 等待同一个进程组中的任何子进程,如果子进程已经加入了别的进程组,waitpid不会等待它

                pid=-1等待任一此时waitpid和wait作用一样

                pid<-1 等待指定进程组中的任何子进程,这个进程组的ID等于pid的绝对值

        status:进程退出时的状态信息,和wait()用法一样

        option:option提供了一些额外的选项来控制waitpid()

                0:同wait(),阻塞父进程,等待子进程退出

                WNOHANG:没有任何已经结束的子进程,则立即返回(非阻塞)

                WUNTRACED:如果子进程暂停了则此函数马上返回,并且不予以理会子进程的结束状态

返回值:

        1,当正常返回的时候,waitpid()返回收集到的已经回收子进程的进程号

        2,如果设置了选项WNOHANG,而调用中waitpid()还有子进程在运行,且没有子进程退出,返回0,父进程的所有子进程都已经退出了返回-1,返回>0表示等到一个子进程退出

        3,如果调用中出错,则返回-1,这时error会被设置成相应的值以指示错误所在

atexit函数

作用:进程在退出前可以用atexit函数注册退出处理函数

注意:

        1,一个进程可以登记最多32个函数,这些函数将由exit自动调用,我们称这些函数为终止处理程序,用atexit函数来登记这些函数

        2,以登记这些函数的相反顺序调用他们,同一函数如登记多次,则也会被调用多次

        3,执行注册的函数依据是当前子进程

语法:

        int atexit (void (*__func)(void))

僵尸进程

子进程退出,父进程没有回收子进程资源,子进程为僵尸进程(有害)

子进程的PID被占用,系统的PID是有数量限制

孤儿进程

父进程先结束,子进程为孤儿进程(无害)

孤儿进程被1号进程接管(当孤儿进程结束时,1号进程负责回收其资源)

守护进程

守护进程是在后台独立运行、脱离控制终端且周期性执行任务或等待处理事件的特殊进程,于系统启动时自动开启并持续至系统关闭,它在系统服务支持(如 httpd 提供 Web 服务)、资源管理(如 syslogd 收集日志)、任务调度(如 cron 按计划执行命令)等多方面发挥关键作用,在 Linux 中创建时需先通过 fork () 创建子进程,父进程退出后子进程进一步执行后续设置步骤以成为守护进程并稳定运行

终端

终端:是与计算机系统相连的一种输入输出设备


在UNIX系统中,用户通过终端登录后得到一个shell进程,这个终端成为shell进程的控制终端,进程中,控制终端是保存在PCB中的信息,而fork会复制PCB中的信息,因此由shell进程启动的其他进程的控制终端也是这个终端
 

作用 : 获取当前进程所属终端名称
#include <unistd.h>
char *ttyname(int fd);
功能:由文件描述符查出对应的文件名
参数: fd: 文件描述符
返回值:
成功:终端名
失败: NULL

进程组

代表一个或多个进程的集合

每个进程都有对应的进程组

进程组ID为当前进程中的第一进程ID

如果一个进程ID和组ID相同,那么这个进程就是组长进程

当父进程创建子进程的时候,默认子进程与父进程属于同一进程组

shell进程启动的进程独立为一个进程组

如果进程中只是组长进程结束,当前进程组不会解散,只有进程组的所有进程离开(终止或转移),该进程组才会解散

一个进程可以为自己或子进程设置进程组ID

注意:组长进程不能设置进程组id


如果进程ID==进程组ID==会话ID,那么该进程为会话首进程

获取所属进程组id

所属头文件

        #include<unistd.h>

函数

        pid_t getpgrp(void)

功能:

        获取当前进程的进程组ID

参数:

       无

返回值:

        总是返回调用者的进程组ID

函数:

        pid_t getpgid(pid_t pid);

        功能:获取指定进程的进程组ID

        参数:

                pid:进程号,如果pid=0,那么该函数作用和getpgrp一样

返回值:

        成功:进程组ID

        失败:-1

设置进程组

函数:

        int setpgid(pid_t pid,pid_t pgid)

功能:

        改变进程默认所属的进程组,通常可以用来加入一个现有的进程组或创建一个新进程组

参数:

        将参1对应的进程,加入参2对应的进程组中

返回值:

        成功:0

        失败:-1

会话

会话是一个或多个进程组的集合

一个会话可以有一个控制终端,这通常是终端设备或伪终端设备,建立与控制终端连接的会话首进程被称为控制进程

一个会话中的几个进程组可以一个前台进程组以及一个或多个后台进程组

如果一个会话有一个控制终端,则它有一个前台进程组,其他进程组为后台进程组

如果终端接口检测到断开连接,则将挂断信号发送至控制进程(会话首进程)

函数getsid

作用:获取会话id

所需头文件

        #include<unistd.h>

函数:

        pid_t getsid(pid_t pid);

参数:

        pid: 进程号,pid为0表示查看当前进程 session ID(会话id)

返回值:

        成功:返回调用进程的会话ID

        失败:-1

组长进程不能成为新会话的首进程,新会话首进程必定会成为组长进程

函数setsid

作用:创建会话

所需头文件:

        #include <unistd.h>

函数:

        pid_t setsid(void);

功能:

        创建一个会话,并以自己的ID设置进程组ID,同时也是新会话的ID,调用了setsid函数的进程,既是新的会长,也是新的组长

参数:

        无

返回值:

        成功:返回调用进程的会话ID

        失败:-1

注意:

        1,组长进程不能设置为会话

        2,需要root权限(ubuntu不需要)

        3,新会话丢弃原有的控制终端,该会话没有控制设备

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

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

相关文章

GitHub Copilot革命性更新:整合顶尖AI模型,如何重塑开发体验?

在技术快速发展的今天&#xff0c;代码辅助工具已成为提升开发效率的利器。今天&#xff0c;我们带来了一个激动人心的消息——GitHub Copilot宣布引入多模型选择功能&#xff0c;这不仅是技术上的一次飞跃&#xff0c;更是对开发者工作流程的一次革新。 多模型选择&#xff1a…

AppFlow:支持飞书机器人调用百炼应用

AppFlow&#xff1a;支持飞书机器人调用百炼应用 简介&#xff1a; 本文介绍了如何创建并配置飞书应用及机器人&#xff0c;包括登录飞书开发者后台创建应用、添加应用能力和API权限&#xff0c;以及通过AppFlow连接流集成阿里云百炼服务&#xff0c;最后详细说明了如何将机器…

华为E9000刀箱(HWE9000V2)服务器硬件监控指标解读

随着数据中心规模的不断扩大&#xff0c;服务器的稳定性和可靠性变得尤为重要。华为E9000刀箱&#xff08;HWE9000V2&#xff09;作为一款高性能的服务器设备&#xff0c;其硬件状态的实时监控对于保障业务的连续性和系统的稳定运行至关重要。 监控易作为一款专业的IT基础设施监…

GWO-SVMD分解 | Matlab实现GWO-SVMD灰狼算法优化逐次变分模态分解

GWO-SVMD分解 | Matlab实现GWO-SVMD灰狼算法优化逐次变分模态分解 目录 GWO-SVMD分解 | Matlab实现GWO-SVMD灰狼算法优化逐次变分模态分解效果一览基本介绍程序设计参考资料 效果一览 基本介绍 GWO-SVMD灰狼算法优化逐次变分模态分解 内有15种用以优化svmd的适应度函数&#…

景联文科技:高质量数据采集标注服务引领AI革新

在当今这个数字化时代&#xff0c;数据已经成为推动社会进步和产业升级的关键资源。特别是在人工智能领域&#xff0c;高质量的数据是训练出高效、精准的AI模型的基础。景联文科技是一家专业的数据采集与标注公司&#xff0c;致力于为客户提供高质量的数据处理服务&#xff0c;…

pycharm添加gitee插件

一、拉取gitee上托管的代码到本地&#xff0c;用pycharm运行 前置条件 1.安装python运行环境 2.安装pycharm 安装&#xff1a;https://blog.csdn.net/m0_65482549/article/details/141394352 1.3.安装git git config --global user.name “" git config --global user.em…

Echarts 绘制地图

一、Apache Echarts 官网地址&#xff1a;https://echarts.apache.org/ npm install echarts --save 二、获取地图的GeoJSON 地址&#xff1a;DataV.GeoAtlas地理小工具系列 左侧是地图&#xff0c;右侧是JSON数据路径&#xff0c;点击你想要生成的地图省市、地级&#xff0…

DHCP服务(包含配置过程)

目录 一、 DHCP的定义 二、 使用DHCP的好处 三、 DHCP的分配方式 四、 DHCP的租约过程 1. 客户机请求IP 2. 服务器响应 3. 客户机选择IP 4. 服务器确定租约 5. 重新登录 6. 更新租约 五、 DHCP服务配置过程 一、 DHCP的定义 DHCP&#xff08;Dynamic Host Configur…

html+css+js网页设计 旅游 厦门旅游网14个页面

htmlcssjs网页设计 旅游 厦门旅游网14个页面 网页作品代码简单&#xff0c;可使用任意HTML辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 1&am…

springboot(20)(删除文章分类。获取、更新、删除文章详细)(Validation分组校验)

目录 一、删除文章分类功能。 &#xff08;1&#xff09;接口文档。 1、请求路径、请求参数。 2、请求参数。 3、响应数据。 &#xff08;2&#xff09;实现思路与代码书写。 1、controller层。 2、service接口业务层。 3、serviceImpl实现类。 4、mapper层。 5、后端接口测试。…

现代化水库可视化管理平台:提升水库运行效率与安全保障

随着科技的飞速发展&#xff0c;现代化水利管理逐渐依赖于数字化、智能化手段。作为水利基础设施的重要组成部分&#xff0c;水库的管理不仅关乎水资源的合理利用&#xff0c;还关系到防洪、灌溉、供水等多项社会功能的实现。为了提升水库的管理水平&#xff0c;确保其运行安全…

【05】Selenium+Python 两种文件上传方式(AutoIt)

上传文件的两种方式 一、input标签上传文件 可以用send_keys方法直接上传文件 示例代码 input标签上传文件import time from selenium import webdriver from chromedriver_py import binary_path # this will get you the path variable from selenium.webdriver.common.by i…

【论文笔记】Number it: Temporal Grounding Videos like Flipping Manga

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: Number it: Temporal Grou…

软件/游戏提示:mfc42u.dll没有被指定在windows上运行如何解决?多种有效解决方法汇总分享

遇到“mfc42u.dll 没有被指定在 Windows 上运行”的错误提示&#xff0c;通常是因为系统缺少必要的运行库文件或文件损坏。以下是多种有效的解决方法&#xff0c;可以帮助你解决这个问题&#xff1a; 原因分析 出现这个错误的原因是Windows无法找到或加载MFC42u.dll文件。这可…

网络地址转换

NAT概述 解决公有地址不足&#xff0c;并且分配不均匀的问题 公有地址&#xff1a;由专门的机构管理、分配&#xff0c;可以在因特网上直接通信 私有地址&#xff1a;组织和个人可以任意使用&#xff0c;只能在内网使用的IP地址 A、B、C类地址中各预留了一些私有IP地址 A&…

机器学习-神经网络(BP神经网络前向和反向传播推导)

1.1 神经元模型 神经网络(neural networks)方面的研究很早就已出现,今天“神经网络”已是一个相当大的、多学科交叉的学科领域.各相关学科对神经网络的定义多种多样,本书采用目前使用得最广泛的一种,即“神经网络是由具有适应性的简单单元组成的广泛并行互连的网络,它的组织能够…

uniapp组建scroll-view初始化页面设置scrollTop无效解决办法

官方文档&#xff1a;scroll-view | uni-app官网 一 . scroll-view的基本用法 使用竖向滚动时&#xff0c;需要给 <scroll-view> 一个固定高度&#xff0c;通过 css 设置 height&#xff1b; <scroll-view :scroll-top"scrollTop" scroll-y"true&quo…

Web day02 Js Vue Ajax

目录 1.javascript: 1.js的引入方式&#xff1a; 2.js变量 & 数据类型 & 输出语句&#xff1a; 模板字符串&#xff1a; 3.函数 & 自定义对象&#xff1a; 4. json 字符串 & DOM操作&#xff1a; 5. js事件监听&#xff1a; 6.js的模块化导入或者导出&a…

【面向对象的程序设计——集合框架】主要接口

文章目录 主要接口集合框架的主要接口Collect接口Set接口实现Set接口的类SortedSet接口 List接口&#xff1a;线性表实现List接口的类&#xff1a; Queue接口实现Queue接口的类 Map接口Map接口的定义Map接口的方法SortedMap接口 主要接口 集合框架的主要接口 声明了对各种集合…

工业物联网网关在设备接入物联网中的核心作用

一、工业物联网网关的定义与功能 工业物联网网关是工业领域中的一种重要设备&#xff0c;它位于工业物联网系统的边缘位置&#xff0c;负责连接、管理和协调工业设备与云平台之间的通信。作为边缘计算的关键组件&#xff0c;工业物联网网关能够实现工业设备、传感器、PLC、DCS…