Linux进程概念(个人笔记)
Linux进程概念
- 1.冯诺依曼体系结构
- 2.操作系统(先描述,再组织)
- 3.进程
- 3.1查看进程的方式
- 3.2通过系统调用获取进程标识符
- 3.4查看进程中常见字段状态的指令
- 3.3fork创建子进程
- 3.3.1fork的原理
- 3.4进程状态
- 3.5进程优先级
- 3.5.1Linux内核的调度队列与调度原理
- 3.6环境变量
- 3.6.1常见的环境变量
- 3.6.2查看环境变量的方法
- 3.6.3和环境变量相关的命令
- 3.6.4环境变量的组织方式
- 3.6.5通过代码获取环境变量
- 3.6.6通过系统调用获取或设置环境变量
- 3.6.7环境变量通常是具有全局属性的
- 3.6.8Linux的命令分类
- 4.进程地址空间
- 4.1地址空间与区域划分
1.冯诺依曼体系结构
输入设备:包括键盘,鼠标,话筒,摄像头,usb,磁盘等
中央处理器(CPU):含运算器和控制器
输出设备:显示器等
存储器:内存
注意:
cpu能且只能对内存进行读写,不能访问外设
外设要输入或者输出数据,也只能写入内存或者从内存中读取
原因可以用木桶原理来解释,cpu的计算和读取速率是纳秒级别的,内存的读取速率是微妙到纳秒级别的,而输入输出单元读取速率是毫秒到微妙级别的,如果说cpu直接和输入输出单元打交道,二者速率相差甚远,也就会大量出现cpu等输入输出单元,会拉低cpu的效率,所以cpu在设置上不会直接和输入输出单元打交道
在程序运行之前,必须先加载到内存,程序=代码+数据,最终都要CPU来处理,CPU需要先读取到这些代码和数据,而CPU和内存有“数据(二进制层面)”层面的交互,也就是exe可执行程序,本质上还是一个文件,只能在磁盘中保存
2.操作系统(先描述,再组织)
操作系统是一款进行软硬件管理的软件,也就是第一个加载的程序
操作系统存在的意义是:为了将软硬件管理好,给用户提供良好(稳定,高效,安全)使用环境
操作系统包括:
内核(进程管理,内存管理,文件管理,驱动管理)
其他程序(函数库,shell外壳程序等等)
操作系统管理硬件:用struct结构体描述要管理的硬件,然后用双向链表其他更加适用的数据结构来组织
操作系统不会去相信任何人,但又要为人提供服务,所以操作系统会暴露自己的部分接口,供上层开发使用,也叫做系统调用
库就是系统调用的函数封装的结合体
3.进程
程序vs进程
程序是在磁盘上的exe可执行程序
而进程是可执行程序从磁盘上拷贝到内存中,操作系统为了管理进程会生成相应的PCB结构体来管理内存中的程序
所以进程=内存中运行的可执行程序+PCB结构体
所以操作系统管理进程其实是对PCB结构体形成各种数据结构进行管理
PCB在Liunx里是task_struct
task_struct
{//标示符: 描述本进程的唯一标示符,用来区别其他进程//状态: 任务状态,退出代码,退出信号等//优先级: 相对于其他进程的优先级。//程序计数器: 程序中即将被执行的下一条指令的地址//内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针//上下文数据: 进程执行时处理器的寄存器中的数据//I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表//其他信息
}
需要注意的是进程PCB不是只在一个数据结构里,而是同时存在多个数据结构里
struct task_struct
{struct task_struct* next;struct task_struct* prev;struct dlist list;//系统所有程序所在的列表struct dlist queue;//同时这个进程还可以在队列中//也可以在各种其他结构中!!!
}
struct dlist
{struct dlist* next;struct dlist* prev;
}
//这里是取task_struct里的各种字段的一种方式
#define curr(list) (struct task_struct*)((int)&list-(int)&(task_struct*)0->list)
curr(list)->pid;
3.1查看进程的方式
ls /proc/
top
ps
3.2通过系统调用获取进程标识符
#include<stdio.h>
#include<sys.types.h>
#include<unistd.h>
int main()
{printf("pid:%d\n",getpid());printf("ppid:%d\n",getppid());return 0;
}
3.4查看进程中常见字段状态的指令
while :; do ps ajx | head -1 && ps ajx | grep mytest | grep -v grep;sleep 1;echo "-----------------------";done
3.3fork创建子进程
创建一个进程,就是系统中要申请内存,保存当前进程的可执行程序+task_struct对象,并将task_struct对象添加到进程列表中。
fork有两个返回值,给子进程返回0,给父进程返回子进程的pid
父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝)
fork之后通常要用if进行分流
3.3.1fork的原理
fork创建子进程,系统中会多一个子进程,它会以父进程为模板,为子进程创建PCB,父子的代码是共享的,但数据是各自私有一份。
fork之后如果没有if-else分流的话,会执行一样的代码,fork之前的代码是只有父进程在执行,那为什么子进程不执行fork之前的代码呢,其原因是pc/eip执行fork完毕,eip指向fork后序的代码,eip在pcb内部保存,所以eip也会被子进程继承。
fork之后父子进程谁先运行这个问题,其实是不确定的因为创建完成之后,与系统的其他进程都要被调度执行,PCB都在运行队列中排队,这要看哪个进程的PCB先被选择调度,哪个进程就先运行,而运行的先后由各自PCB中调度信息(时间片,优先级等)+调度器算法共同决定。
进程的独立性,体现在各自有自己的PCB进行之间不会相互影响,而共享的代码本身是只读,无法修改,代码共享,数据各自私有一份。
fork有两个返回值的原因在于,fork就是一个函数,函数有返回值,fork之后代码共享,return也要被共享,父进程被调度要执行return,子进程也是如此,所以有两个返回值
但更准确的讲法,真实情况是操作系统通过一些寄存器做到返回值返回两次
3.4进程状态
R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里
S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠(interruptible sleep))
D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束
T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行
X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态
Z(zombie)-僵尸进程:是一个比较特殊的状态。当进程退出并且父进程(使用wait()系统调用)没有读取到子进程退出的返回代码时就会产生僵死(尸)进程,僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态
维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说,Z状态一直不退出,PCB一直都要维护,一直会占用内存,而没有去释放掉,久而久之内存占满,一连串的崩溃。
孤儿进程:父进程先退出,子进程就称之为“孤儿进程”,孤儿进程被1号init进程领养,之后会被init进程回收
3.5进程优先级
排队的本质:就是在确认优先级
基本概念:cpu资源分配的先后顺序,就是指进程的优先权(priority)
进程会有优先级的原因:本质是资源不足
进程的优先级其实是PCB中的PRI字段确认,数值越小,优先级越大
Linux进程的优先级数值范围:60~99
Linux中默认进程的优先级都是80
Linux是支持动态优先级调整的
Linux进程pcb中存在一个nice值:进程优先级的修正数据
pri(新)=pri(old)+nice
pri(old)都是从80开始的!
nice调整最小是:-20,超过部分统一当成-20
nice调整最大是:19,超过部分统一当成19
把优先级限定在一定的范围内其原因是:OS调度的时候,较为均衡的让每个进程都要得到调度,如果不控制在一定范围容易导致优先级较低的进程,长时间得不到CPU资源,也就是进程饥饿
修改nice值的方法
top
#进入后按r->输入进程PID->输入nice值
3.5.1Linux内核的调度队列与调度原理
运行队列会有两个字段,一个是活动队列另一个是过期队列
nr_active:总共有多少个运行状态的进程
queue[140]:一个元素就是一个进程队列,优先级相同的进程按照FIFO规则进行排队调度,数组下标就是优先级
bitmap[5]:一共140个优先级,一共140个进程队列,而bitmap有160个bit位,这里的比特位是用来判断队列是否为空,提高查找效率
本质上os当前运行的队列是活动队列,另一个队列就是过期队列,然而你所添加的进程会纳入过期队列中,等到当前活动队列的进程执行完,os就会调度到过期队列,也就是过期队列成了活动队列
值的注意的是Linux进程的优先级数值范围:60~99,也就是40个等级,其实总共有140个等级,前100个等级叫实时优先级,后40个叫普通优先级,我们能操作的时后40个,nice值也只与后四十个有关。
3.6环境变量
基本概念:环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
3.6.1常见的环境变量
PATH : 指定命令的搜索路径
HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
SHELL : 当前Shell,它的值通常是/bin/bash。
3.6.2查看环境变量的方法
echo $NAME #NAME:你的环境变量名称
3.6.3和环境变量相关的命令
- echo: 显示某个环境变量值
- export: 设置一个新的环境变量
- env: 显示所有环境变量
- unset: 清除环境变量
- set: 显示本地定义的shell变量和环境变量
3.6.4环境变量的组织方式
每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串
3.6.5通过代码获取环境变量
- 命令行第三个参数
#include <stdio.h>
int main(int argc, char *argv[], char *env[])
{int i = 0;for(; env[i]; i++){printf("%s\n", env[i]);}return 0;
}
- 通过第三方变量environ获取
#include <stdio.h>
int main(int argc, char *argv[])
{extern char **environ;//environ是全局变量,里面存储的是int i = 0;for(; environ[i]; i++){printf("%s\n", environ[i]);}return 0;
}
3.6.6通过系统调用获取或设置环境变量
#include <stdio.h>
#include <stdlib.h>
int main()
{printf("%s\n", getenv("PATH"));return 0;
}
3.6.7环境变量通常是具有全局属性的
环境变量通常具有全局属性,可以被子进程继承下去
#include <stdio.h>
#include <stdlib.h>
int main()
{char * env = getenv("MYENV");if(env){printf("%s\n", env);}return 0;
}
直接查看,发现没有结果,说明该环境变量根本不存在
其实是没有导入该环境变量
export MYENV="hello world"
再次运行程序,发现结果有了,说明:环境变量是可以被子进程继承下去
命令行启动的进程都是shell/bash的子进程,子进程的命令行参数和环境变量,是父进程bash给我们传递的。
我们直接更改的是bash进程内部的环境变量信息!
每一次重新登陆,都会给我们形成新的bush解释器并且新的bash解释器自动从读取形成自己的环境变量表信息!
环境变量信息是以脚本配置文件的形式存在的!
每一次登录的时候,bash进程都会读取 vim .bash_profile
配置文件的内容,为我们bash进程形成一张环境变量表信息!
本地变量只在bash进程内部有效,不会被子进程继承下去,环境变量是通过让所有的子进程继承的方式,实现自身的全局性
3.6.8Linux的命令分类
- 常规命令,shell fork让子进程执行的
- 内建命令,shell命令行的一个函数,当然可以直接读取shell内部定义的本地变量
4.进程地址空间
语言层面
系统层面
这里是fork后,子进程与父进程的代码共享,数据各自私有一份,子进程会拷贝父进程的task_struct,task_struct里的mm_struct所指向的进程地址空间也会拷贝一份,进程地址空间与物理地址所链接的页表也要拷贝一份,当子进程对其数据进行修改时,会进行写时拷贝,本拷贝下来父子进程代码和数据共享的,因为修改了数据,os会在内存中另开辟一块空间数据进行私有,让子进程页表中虚拟地址所对应的物理地址进行重新指向新的地址,但其虚拟地址并未进行修改,所以造成在语言层面,同一个地址出现两个不同值的情况。
关于页表不止只有虚拟地址和物理地址,还有访问权限字段,和是否分配&&是否有内容。
访问权限字段实现了代码段只能读不能写的功能
而内存是否分配和是否有内容体现在Linux的进程挂起状态
4.1地址空间与区域划分
地址空间也要被OS管理起来,每一个进程都要有地址空间,系统中一定要对地址空间做管理(先描述再组织),地址空间最终一定是一个内核的数据结构对象,就是一个内核结构体。
让进程以统一的视角看待内存,所以任意一个进程,可以通过地址空间+页表可以将乱序的内存数据,变成有序,分门别类的规划好。
存在虚拟地址空间,可以有效的进行进程访问内存的安全检查。
将进程管理和内存空间管理进行解耦
通过页表,让进程映射到不同的物理内存中,从而实现进程的独立性
父进程创建子进程的时候首先将自己的读写权限,改成只读,然后再创建子进程。
当父进程形成子进程之后,子进程写入,会发生写实拷贝(重新申请内存,进行拷贝,修改页表),页表转换会因为权限问题出错
- 真的出错了
- 不是出错,触发我们进行重新申请内存
这里是操作系统介入
相关文章:

Linux进程概念(个人笔记)
Linux进程概念 1.冯诺依曼体系结构2.操作系统(先描述,再组织)3.进程3.1查看进程的方式3.2通过系统调用获取进程标识符3.4查看进程中常见字段状态的指令3.3fork创建子进程3.3.1fork的原理 3.4进程状态3.5进程优先级3.5.1Linux内核的调度队列与…...

每天五分钟计算机视觉:如何在现有经典的卷积神经网络上进行微调
本文重点 在深度学习领域,卷积神经网络(Convolutional Neural Networks,CNN)因其强大的特征提取和分类能力而广泛应用于图像识别、自然语言处理等多个领域。然而,从头开始训练一个CNN模型往往需要大量的数据和计算资源,且训练时间较长。幸运的是,迁移学习(Transfer Le…...
10个典型的MySQL笔试题和面试题
提供10个典型的MySQL笔试题和面试题作为示例,并给出答案或解释。如果需要更多题目,可以根据这些示例进行扩展或参考相关文档。 1. MySQL是什么? 答案:MySQL是一个关系型数据库管理系统(RDBMS),…...

AI大模型的TTS评测
L-MTL(Large Multi-Task Learning)Models 是一种大规模多任务学习模型,通过结合 Mixture of Experts(MMoE)框架与 Transformer 模型,实现对 TTS(Text-to-Speech)系统中多个评估指标的…...

推荐一款可以下载B站视频和音频的工具
cobalt是一个免费的下载网站,主要是用于载视频和音频。只要你把相应的网址复制下来,然后打开cobalt网站,黏贴网址,选择要下载的格式,就可以下载相应的音频或者视频了。 该网站非常简洁,使用也很简单。目前只…...

中科数安 |-透明加密软件_无感透明加密 - 源头有保障
中科数安的透明加密软件是一款专为保护企业数据安全而设计的高级产品,它采用了无感透明加密技术,确保源头数据的安全可靠。 ——www.weaem.com 以下是该软件的主要特点和功能概述: 无感透明加密: 中科数安的透明加密软件能够在用…...

ui自动化selenium,清新脱俗代码,框架升级讲解
一:简化 1. 新建common 包 新建diver.py 封装浏览器驱动类 from selenium import webdriverclass Driver():"""浏览器驱动类定义 一个【获取浏览器驱动对象driver的方法】。支持多种类型浏览器"""def get_driver(self,browser_typ…...

【吊打面试官系列-Mysql面试题】Myql 中的事务回滚机制概述 ?
大家好,我是锋哥。今天分享关于 【Myql 中的事务回滚机制概述 ?】面试题,希望对大家有帮助; Myql 中的事务回滚机制概述 ? 事务是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个不可分割的工作单位…...

VMware虚拟机三种网络模式设置 - Bridged(桥接模式)
一、前言 由于linux目前很热门,越来越多的人在学习linux,但是买一台服务放家里来学习,实在是很浪费。那么如何解决这个问题?虚拟机软件是很好的选择,常用的虚拟机软件有vmware workstations和virtual box等。 在使用虚…...

关于Panabit在资产平台中类型划分问题
现场同事问了一个问题:Panabit能不能当做CentOS接入? 我第一反应是:Panabit是个什么鬼?为啥要混编接入?后期维护都是事啊。所以,我就想回答:不能! 但是,最好要给出一个…...

【C语言】12.C语言内存函数
文章目录 1.memcpy使用和模拟实现2.memmove使用和模拟实现3.memset函数的使用4.memcmp函数的使用 memcpy:内存拷贝 memmove:内存移动 memset:内存设置 memcmp:内存比较 1.memcpy使用和模拟实现 memcpy:内存拷贝 void…...
Django:如何将多个数据表内容合在一起返回响应
一.概要 Django写后端返回响应时,通常需要返回的可能不是一个数据表的内容,还包括了这个数据表的外键所关联的其他表的一些字段,那该如何做才能把他们放在一起返回响应呢? 二.处理方法 在这里我有三个数据表 第一个是航空订单&…...

棱镜七彩荣获CNNVD两项大奖,专业能力与贡献再获认可!
6月18日,国家信息安全漏洞库(CNNVD)2023年度工作总结暨优秀表彰大会在中国信息安全测评中心成功举办。棱镜七彩凭借在漏洞方面的突出贡献和出色表现,被授予“2023年度优秀技术支撑单位”与“2023年度最佳新秀奖”。 优秀技术支撑单…...

uni-app中使用富文本rich-text个人经验
rich-text是在uni-app一个内置组件,用于高性能地渲染富文本内容。先贴一下官方的属性列表: 先说一下“selectable” 长按选择区域复制,这个我在APP项目中 不起作用,可能像文档说的,只支持“百度小程序”吧。在APP端起作…...

Matlab|基于V图的配电网电动汽车充电站选址定容-可视化
1主要内容 基于粒子群算法的电动汽车充电站和光伏最优选址和定容 关键词:选址定容 电动汽车 充电站位置 仿真平台:MATLAB 主要内容:代码主要做的是一个电动汽车充电站和分布式光伏的选址定容问题,提出了能够计及地理因素和服…...

从零开始! Jupyter Notebook的安装教程
🚀 从零开始! Jupyter Notebook的安装教程 摘要 📄 Jupyter Notebook 是一个广受欢迎的开源工具,特别适合数据科学和机器学习的开发者使用。本文将详细介绍从零开始安装 Jupyter Notebook 的步骤,包括各种操作系统的安装方法&am…...
web前端信息卡:深入探索与实用指南
web前端信息卡:深入探索与实用指南 在数字化时代,web前端信息卡已成为我们日常生活和工作中的重要组成部分。这些小巧而强大的工具,能够在有限的空间内展示丰富的信息,提升用户体验。然而,设计一个出色的web前端信息卡…...

之所以选择天津工业大学,因为它是双一流、报考难度适宜,性价比高!天津工业大学计算机考研考情分析!
天津工业大学(Tiangong University),简称“天工大”,位于天津市,是教育部与天津市共建高校、国家国防科技工业局和天津市共建的天津市重点建设高校、国家“双一流”建设高校、天津市高水平特色大学建设高校、中国研究生…...

WPF三方UI库全局应用MessageBox样式(.NET6版本)
一、问题场景 使用HandyControl简写HC 作为基础UI组件库时,希望系统中所有的MessageBox 样式都使用HC的MessageBox,常规操作如下: 在对应的xxxx.cs 顶部使用using 指定特定类的命名空间。 using MessageBox HandyControl.Controls.Message…...

ABAP-03基础数据类型
基本数据类型 数据类型默认大小(byte)有效大小初始值说明示例C11-65535SPACE文本字符(串)‘Name’N11-65535‘00…0’数字文本‘0123’T66‘000000’时间(HHMMSS)‘123010’D88‘00000000’日期(yyyymmdd)‘20090901’I4-231~232…...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

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

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...

华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

android RelativeLayout布局
<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...
在树莓派上添加音频输入设备的几种方法
在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...