当前位置: 首页 > news >正文

linux高级系统编程之进程

进程

一个正在进行的程序

并行与并发

并行:执行的程序在不同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,新会话丢弃原有的控制终端,该会话没有控制设备

相关文章:

linux高级系统编程之进程

进程 一个正在进行的程序 并行与并发 并行:执行的程序在不同CPU上同时执行 并发:一个CPU,多个进程交替执行,因为交替速度很快,所以从宏观上来看是同时执行的,但是从围观的角度是交替执行的 单道与多道 单道程序设计:所有进程一个一个排队执行,若A阻塞,B只能等待,,即使CPU处于空…...

nextjs+nestjs+prisma写todolist全栈项目

技术栈 nextjsnestjsprisma所学知识 Nextjs组件渲染,状态,路由docker启动Mysql容器prisma操作Mysql(CRUD)允许跨域请求APITanStack Query异步状态管理fetch api服务器组件预请求数据nestjs 管道和异常处理检测id是否正整数Docker启动Mysql容器 compose.yml name: todoLis…...

基于Matlab的图像去噪算法仿真

中值滤波的仿真 本节选用中值滤波法对含有高斯噪声和椒盐噪声的图像进行去噪&#xff0c;并用Matlab软件仿真。 &#xff08;1&#xff09;给图像加入均值为0&#xff0c;方差为0.02的高斯噪声&#xff0c;分别选择33模板、55模板和77模板进行去噪 Matlab部分代码&#xff1…...

Docker pull镜像拉取失败

因为一些原因&#xff0c;很多镜像仓库拉取镜像失败&#xff0c;所以需要更换不同的镜像&#xff0c;这是2024/11/25测试可用的仓库。 标题1、 更换镜像仓库的地址&#xff0c;编辑daemon.json文件 vi /etc/docker/daemon.json标题2、然后将下面的镜像源放进去或替换掉都可以…...

fastjson不出网打法—BCEL链

前言 众所周知fastjson公开的就三条链&#xff0c;一个是TemplatesImpl链&#xff0c;但是要求太苛刻了&#xff0c;JNDI的话需要服务器出网才行&#xff0c;BCEL链就是专门应对不出网的情况。 实验环境 fastjson1.2.4 jdk8u91 dbcp 9.0.20 什么是BCEL BCEL的全名应该是…...

vue2 中使用 Ag-grid-enterprise 企业版

文章目录 问题Vue2 引入企业版不生效npm run dev 时卡住了94% after seal 卡在这里了测试打包源 git 解决方案记录 问题 我想用企业版的树状表格 Vue2 引入企业版不生效 编译引入 // vue.config.js module.exports {transpileDependencies: ["ag-grid-enterprise"…...

Redis开发03:常见的Redis命令

1.输入以下命令&#xff0c;启动redis。 sudo service redis-server start 如果你是直接安装在WSL的&#xff0c;搜索栏搜索Ubuntu或者点击左下角Windows图表找到U那一栏&#xff0c;直接打开Ubentu&#xff0c;输入账密后&#xff0c;输入“sudo service redis-server start”…...

研0找实习【学nlp】14--BERT理解

​​​​​以后做项目&#xff0c;一定要多调查&#xff0c;选用不同组合关键词多搜索&#xff01; BERT论文解读及情感分类实战_bert模型在imdb分类上的准确率已经到达了多少的水平-CSDN博客 【深度学习】-Imdb数据集情感分析之模型对比&#xff08;4&#xff09;- CNN-LSTM…...

mysql之基本常用的语法

mysql之基本常用的语法 1.增加数据2.删除数据3.更新/修改数据4.查询数据4.1.where子句4.2.order by4.3.limit与offset4.4.分组与having4.5.连接 5.创建表 1.增加数据 insert into 1.指定列插入 语法&#xff1a;insert into table_name(列名1,列名2,....,列名n) values (值1,值…...

基于Linux的patroni搭建标准

作者&#xff1a;Digital Observer&#xff08;施嘉伟&#xff09; Oracle ACE Pro: Database PostgreSQL ACE Partner 11年数据库行业经验&#xff0c;现主要从事数据库服务工作 拥有Oracle OCM、DB2 10.1 Fundamentals、MySQL 8.0 OCP、WebLogic 12c OCA、KCP、PCTP、PCSD、P…...

2024年第十三届”认证杯“数学中国数学建模国际赛(小美赛)

↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓...

Unity类银河战士恶魔城学习总结(P149 Screen Fade淡入淡出菜单)

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili 教程源地址&#xff1a;https://www.udemy.com/course/2d-rpg-alexdev/ 本章节实现了进入游戏和死亡之后的淡入淡出动画效果 UI_FadeScreen.cs 1. Animator 组件的引用 (anim) 该脚本通过 Animator 控制 UI 元…...

(四)3D视觉机器人的手眼标定(眼在手外)

内容 1.背景介绍1.1 思路T_target_to_cam求解公式求解 2.操作流程 1.背景介绍 3D视觉机器人指的是机器人通过3D相机提供的3D点云视觉信息&#xff0c;完成某些实际的功能。   目标是将场景信息从相机坐标系变换至机械臂坐标系中&#xff0c;最终是获得相机到机械臂基座的空间…...

安达发|制造业APS智能优化排产软件的四类制造模型解决方案

在制造业中&#xff0c;APS&#xff08;高级计划和排程系统&#xff09;智能优化排产软件的应用越来越广泛。它通过集成先进的算法和模型&#xff0c;帮助企业提高生产效率、降低成本并提升客户满意度。针对不同类型的生产需求&#xff0c;APS软件提供了四类制造模型解决方案&a…...

命令行使用ssh隧道连接远程mysql

本地电脑A 跳板机B 主机2.2.2.2 用户名 B ssh端口号22 登录密码bbb 远程mysql C 地址 3.3.3.3 端口号3306 用户名C 密码ccc A需要通过跳板机B才能访问C; navicat中配置ssh可以实现在A电脑上访问C 如何实现本地代码中访问C呢? # 假设本地使…...

力扣第 71 题 简化路径

一、题目描述 给定一个字符串 path&#xff0c;表示一个由目录名和斜杠 "/" 组成的绝对路径&#xff0c;请简化该路径&#xff0c;使其变为规范路径。 在 Unix 风格的文件系统中&#xff1a; 一个点 "." 表示当前目录本身&#xff1b;两个点 "..&q…...

使用ENSP实现OSPF

一、项目拓扑 二、项目实现 1.路由器AR1配置 进入系统试图 sys将路由器命名为R1 sysname R1关闭信息中心 undo info-center enable 进入g0/0/0接口 int g0/0/0将g0/0/0接口IP地址配置为1.1.1.1/24 ip address 1.1.1.1 24进入g0/0/1接口 int g0/0/1将g0/0/1接口IP地址配置为2…...

分布式下怎么优化处理数据,怎么代替Join

分布式下怎么优化处理数据&#xff0c;怎么代替Join 简单来说&#xff0c; 可以采用 数据冗余&#xff0c;有意地存储一些重复的数据&#xff0c;以此减少关联查询的需求 数据拆分与多次查询&#xff0c;将一次获取的多表数据&#xff0c;拆分多个单独的查询 使用数据仓库…...

51单片机快速入门之中断的应用 2024/11/23 串口中断

51单片机快速入门之中断的应用 基本函数: void T0(void) interrupt 1 using 1 { 这里放入中断后需要做的操作 } void T0(void)&#xff1a; 这是一个函数声明&#xff0c;表明函数 T0 不接受任何参数&#xff0c;并且不返回任何值。 interrupt 1&#xff1a; 这是关键字和参…...

[Java]微服务配置管理

介绍 代码拆分为微服务后, 每个服务都有自己的配置文件, 而这些配置文件中有很多重复的配置, 并且配置变化后需要重启服务, 才能生效, 这样就会影响开发体验和效率 配置管理服务可以帮助我们集中管理公共的配置, 并且nacos就可以实现配置管理服务 配置共享 我们可以把微服务共…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

AI语音助手的Python实现

引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...

Leetcode33( 搜索旋转排序数组)

题目表述 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...

【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权

摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题&#xff1a;安全。文章将详细阐述认证&#xff08;Authentication) 与授权&#xff08;Authorization的核心概念&#xff0c;对比传统 Session-Cookie 与现代 JWT&#xff08;JS…...