linux进程——学习笔记(代码片段)

正义的伙伴啊 正义的伙伴啊     2022-12-06     710

关键词:

文章目录

认识操作系统

冯诺依曼体系结构是计算机的基本结构


该结构规定了 cpu(中央处理器) 只和内存进行交互,任何其他设备 例如 输出设备 和 输入设备 都必须把数据加载到内存上,才能被cpu读写

那么为什么要把所有数据都加载到内存中才能被cpu读写?
这是因为不同硬件数据传输的效率不同,cpu读取数据的速度 是 硬盘上传数据的1000万倍,这样两种设备如果直接交互会导致cpu性能大幅度下降,所以需要内存来在中间来当一个缓冲,内存的容量虽然比硬盘小不少,但是传输速度比硬盘快不少,但是和cpu的速度还是差远了,于是 内存 上还有多层的高速缓存,这些高速缓存直接和cpu交互。传输速度越快的设备 ,单位容量的造价越高,所以分级存储是一种最经济的结构,这也是电脑能被大众使用的原因

操作系统

操作系统是进行软硬件资源管理的软件
例如:数据从 外设上加载到内存中,再从内存中被cpu使用、我们写一个c语言程序在屏幕上打印一段文字,这段文字是怎么从内存,到屏幕上(外设)。这些全部是操作系统的功劳


上图显示了操作系统的大致功能:

  • 自上而下:将用户的指令、数据传递给底层的硬件
  • 自下而上:将由硬件输入的数据传递到内存,以供用户使用
    从上还可以发现计算机体系是一个层状结构,任何操作都要经过中间操作系统之手,每一层之间下层通过暴露接口来供上层调用!
    从中可以看出 操作系统实际上是对上层、下层的数据的 管理,实际上是一个管理者的角色

所以为什么要有操作系统:

  1. os方便用户使用,降低了计算机的使用成本
  2. os给用户、开发人员提供了一个良好的运行环境
  3. os对下更加高效的使用硬件资源

os对于这么多数据 ,又该如何管理?
首先操作系统用一个抽象的概念来描述这些数据的大体特征 ,虽然这些数据 功能上可能大不相同。这点有点像C语言中类的结构体,这样操作系统就可以以相同的方式来看待这些数据了。一旦这些 数据 以同一种方式去看待 , 这些 数据 就会变成一个一个相同的结构体个体(结构体包含这些数据的描述信息),接下来要管理这些 个体 就可以数据结构来进行管理。通过对数据结构的增删查改来完成对数据的操作。
接下来学的:进程进程地址空间 都是这种抽象化之后的结果,

进程的概念

进程实际上是操作系统对程序的一种管理
一个电脑上可以跑多个程序,为了保证这些程序有序运行、防止恶意软件修改 计算机软件 ,这时就需要os这张看不见的“大手”,将他们安排的明明白白。

os将所有程序抽象成了一个结构体PCB(Linux下为pcb为task_struct结构体),该结构体内有一个进程可能用到的所有信息。这样不同的程序就可以 用一个进程来描述了!进程之间引入了结构体——双向链表 来对这些独立的结构体进行管理。


上图就完成了一个多程序同时运行的情况,从上图我们发现os实现了如下的转换:
os对程序的管理 -> os对进程的管理 -> 对双链表的管理

task_struct的内容

下面了解一下task_struct 的内容

  • 标识符(pid):不同进程如何区分?要有唯一的标识符来区分不同的进程,task_struct用一串数字(pid,ppid)来区分不同的进程,和他们之间的关系
  • 状态:操作系统通过识别task_struct中状态的标识符来了解进程的状况,比方说:有的程序被终止等待被销毁,这时也需要对应的状态来标识,让操作系统来回收这个进程。
  • 优先级:不同进程谁应该优先被执行?需要优先级来标识
  • 程序计数器:程序即将执行的下一条指令的地址,这个是由寄存器来完成,cpu每次执行指令时,都由一个叫eip的寄存器将下一条指令的地址传给cpu计算,例如后面 进程等待 程序计数器就至关重要
  • 上下文数据:进程执行时处理器的寄存器的数据,与进程的切换有关。例如一个进程在运行中,由于某些原因,需要被暂时停止执行,让出cpu。需要进程保存自己的所有临时数据,以便后面再调用该进程时对数据进行恢复!

进程抢占:

进程放在cpu上之后,不是一直运行直到运行结束,每个进程都有一个运行时间单位:时间片,所以有时候当一个进程的时间片到了或者来了一个优先级更高的进程,当前cpu上运行的进程就要被换下来。这就是进程的抢占。

并行 和 并发

  • 单核cpu:一个cpu上只能对一个进程进行计算,那又是如何完成多进程呢?单核cpu通过进程间的快速切换,来达到在一段时间内,让所有进程代码都得到推进——并发
  • 多核cpu:每个cpu上运行一个进程以达到多进程——并行

总结:
进程 = 程序 + 内核申请的PCB数据结构

查看进程

使用 ps -ajx | grep 特定进程的pid

创建进程

创建一个进程需要用到函数pid_t fork()
fork的特性:

  1. 有两个返回值
  2. fork出来的进程叫做子进程,父子进程代码共享,数据各自私有一份

fork的返回值:

  1. 如果是子进程,返回的是0
  2. 如果是父进程,则返回的是子进程的pid

为什么fork有两个返回值:
我们一般认为函数执行到返回值时,主体函数已经执行完了,返回值只是给调用函数返回一个执行结果,所以fork函数主体执行完成时,就已经有两个进程了,两个进程各自执行返回语句,就有了两个返回值

理解fork:

  1. 从用户的角度去看:执行完fork之后,会有两个独立的进程来执行后续的代码,这实际上就是 父子进程之间代码共享,数据各自私有一份。之所以数据要私有一份,是因为进程的独立性
  2. 从os的角度去看:子进程以父进程为模板,其中代码是共享的,数据是写时拷贝

用if语句对父子进程进行分流

首先接受两个函数:
pid_t getpid():返回该进程的pid
pid_t getppid():返回该进程的ppid(父进程的pid)

 #include<stdio.h> 
  2 #include<unistd.h>                                                                             
  3 int main()
  4          
  5   int a=fork();
  6   if(a==0)     
  7          
  8     while(1)
  9            
 10       printf("i am son:   pid: %d  ppid:%d   \\n",getpid(),getppid()); //返回子进程的pid、ppid
 11       sleep(1);                                                      
 12               
 13     
 14   else
 15     while(1)
 16            
 17       printf("i am father:   pid: %d  ppid:%d   \\n",getpid(),getppid()); //返回父进程的pid、ppid
 18       sleep(1);                                                         
 19                                                                        
 20               
 21   return 0;
 22           


在该程序运行的时候,用ps -axj去查看进程状态,发现两个进程都在同时运行

进程的状态

在查看进程状态时,有一列是STAT

这一列显示的是进程的状态,进程的状态在os对进程的管理中也是一个非常重要的信息

  • R运行状态(running):代表进程在要么在运行,要么在运行队列中等待调用
  • S运行状态(sleeping):浅度休眠意味着进程在等待事件的完成,可以对外部事件作出反应,上面的例子中父子进程就是S状态,他们在等待printf将打印的内容刷新到屏幕上
  • D运行状态(disk sleep):深度睡眠状态,无法对外部事件作出反应,即便是操作系统也无法将其杀掉,只能等D自己执行结束。例如:进程A在等待内存想磁盘写入大量数据时,就进入了D状态
  • T运行状态(stopped):进程被停止、挂起
  • X运行状态(dead):这是进程被回收之后的状态,你不会在任务列表里看到这个状态
  • Z运行状态(zonbie):Z状态是一种持续的状态,进程运行结束、退出的时候,会把数据和代码释放,但是PCB是不会释放的,退出的过程中进程会把在执行过程中的执行情况或执行结果写入PCB中,这些进程的返回信息会被os或者他的父进程读取,读取成功之后该进程的PCB才会被释放。在父进程未读取PCB内容的这段时间内,该进程一直处于Z状态,这种进程叫做“僵尸进程” ,且无法被杀掉。总之:僵尸进程是为了保存子进程的运行结果直到被父进程读取(回收)

僵尸进程的危害:僵尸进程由于无法被杀掉,所以os要不断的去维护该进程,所以会一直占用空间,导致内存泄漏。

孤儿进程

孤儿进程就是父进程在子进程运行完之前就已经退出,子进程就无法被父进程回收,此时孤儿进程会被1号进程领养并进行回收

进程的优先级

为什么需要进程的优先级?
进程的优先级决定了进程的执行的顺序,本质上还是cpu的资源有限,优先级决定了cpu的资源该如何分配

优先级和权限的区别
权限:决定你是否能得到资源
优先级:你一定能得到资源只是先后顺序的问题

如何查看进程的优先级?
ps -al
以上信息中:
UID:操作系统用来标识用户的号码
PID:操作系统用来标识进程的号码
PPID:操作系统用来标识 子进程的父进程的号码
PRI:当前进程的优先级
NI:代表这个进程的NICE值,我们通过修改这个值来修改进程的优先级

PRI和NI

  • PRI
    PRI代表的是该进程的优先级,PRI的值越小,优先级越高
  • NI
    NI就是NICE值,一个进程对应一个NICE值,我们修改PRI是通过修改NICE值来完成,关系式为:PRI(new)=PRI(old) + NICE 也就是:修改后的PRI的值等于修改前的PRI值+NICE
    注意: PRI(old)值始终是80,也就是说PRI始终以80为基准来修改的,NICE的取值范围是[-20,20)
    为什么PRI的基准值要设定成始终是80?
    有一个基准自方便调整,而且会始终把PRI的范围控制在[60,100),不会出现较为特别大 或者 特别小的优先级,比方说:有一个恶意程序可以通过多次修改NICE值将PRI修改到一个特别大的值

如何修改优先级

  1. 首先使用ps -al查看进程的pid,记住这个pid值

  2. 输入top,就会进入一个类似于Windows中任务管理器面板的界面,输入r ,并输入修改进程的pid

  3. 输入NICE值

总结
Linux的优先级由PRI和NI共同决定,os为了保证进程之间的公平竞争,所以把 每次PRI的修改的基准值都设为了80 其次把NI的取值范围限制死。

linux学习笔记(代码片段)

文章目录🍋fork()🍓理解fork🍋进程状态🍅操作系统下描述的状态🍅具体的操作系统Linux下的进程状态🥝运行状态就一定在运行吗?🥝S和D的区别🥝T状态🥝Z状态🥝什么样的进程杀不掉... 查看详情

linux学习笔记网络配置进程管理rpm包的管理和yum介绍(代码片段)

...和hosts映射1.4主机名解析过程分析(Hosts、DNS)2.进程管理2.1介绍2.2显示系统执行的进程(ps)2.3终止进程(kill、killal)2.4查看进程树(pstree)2.5动态监控进程(top、netstat)3.服务管理3.1介绍3... 查看详情

linux学习笔记一(代码片段)

linux学习笔记一文章目录linux学习笔记一Linuxpackageoperationoflookingfilesoperationhelpcommandsowncommandsechotunnelechoagainuserorrootprocessingaliasagainfinding这个是我在学习linux系统的时候的一点的小小的总结,希望对大家有一定的在帮助啦。Linux 查看详情

linux学习笔记linux下i/o接口的演变之路(代码片段)

...一个基本概念是Unix/Linux中的一切都是文件的规则。每个进程都有一个指向文件、套接字、设备和其他操作系统对象的文件描述符表。        与许多IO源一起工作的典型系统有一个初始化阶段,然后进入某种待机模式——... 查看详情

进程地址空间——学习笔记(代码片段)

文章目录进程地址空间的划分进程地址空间示意图进程地址空间&物理内存分页页表为什么需要进程地址空间进程地址空间的划分我们在学习C/C++的时候一直会涉及一个概念——地址,以前一直以为地址和物理内存是... 查看详情

python学习笔记(代码片段)

文章目录1.进程1.1.系统原生OS模块,创建进程1.2.multiprocessing模块1.2.1.Process单进程1.2.2.Pool进程池1.3.subprocess模块使用外部子进程2.线程2.1.threading模块,创建线程2.2.锁LOCK2.3.ThreadLocal模块,跨函数使用值1.进程线程是最小的执行单元,... 查看详情

io学习笔记(代码片段)

虚拟文件系统、文件描述符、IO重定向一切皆文件,进程隔离操作系统宏观介绍常用的IO设备有哪些?磁盘、网卡Linux中物理盘是怎么映射到操作系统中的?Kernel中VFS(VirtualFileSystem)在Linux中如果两个程序都去加载同一个文件&... 查看详情

python学习笔记(代码片段)

文章目录1.进程1.1.系统原生OS模块,创建进程1.2.multiprocessing模块1.2.1.Process单进程1.2.2.Pool进程池1.3.subprocess模块使用外部子进程2.线程2.1.threading模块,创建线程2.2.锁LOCK2.3.ThreadLocal模块,跨函数使用值1.进程线程是最小的执行单元,... 查看详情

linux学习笔记(代码片段)

linux学习笔记1.操作系统的发展史1.2Unix1.2Minix1.3Minix1.4Minix没有火起来的原因2.linux介绍2.1Linux内核版本2.2Linux发行版本2.3Linux目录结构2.4用户目录3.命令行的基本用法3.1命令的使用方式3.2查看帮助文档3.3tab自动补全3.4history游览历史3.5... 查看详情

linux进程——学习笔记(代码片段)

...操作系统冯诺依曼体系结构是计算机的基本结构操作系统进程的概念task_struct的内容进程抢占:并行和并发查看进程创建进程理解fork:进程的状态孤儿进程进程的优先级认识操作系统冯诺依曼体系结构是计算机的基本结... 查看详情

python学习笔记-day-9(代码片段)

进程与线程什么是线程(thread)?线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行... 查看详情

imx6ull学习笔记——获取和编译linux内核(代码片段)

...核架构,即Linux大部分功能都会在内核中实现,如进程管理、内存管理、设备管理、文件管理以及网络管理等功能,Linux在发展的过程中,引入了内核模块(LoadableKernelModule,LKM)机制& 查看详情

imx6ull学习笔记——获取和编译linux内核(代码片段)

...核架构,即Linux大部分功能都会在内核中实现,如进程管理、内存管理、设备管理、文件管理以及网络管理等功能,Linux在发展的过程中,引入了内核模块(LoadableKernelModule,LKM)机制& 查看详情

imx6ull学习笔记——获取和编译linux内核(代码片段)

...核架构,即Linux大部分功能都会在内核中实现,如进程管理、内存管理、设备管理、文件管理以及网络管理等功能,Linux在发展的过程中,引入了内核模块(LoadableKernelModule,LKM)机制& 查看详情

linux学习笔记(代码片段)

Linux学习笔记(二)Author:akynazhBlog:akynazh.site一些文件操作pwdpwd[-P]-P:显示出确实的路径,而非使用链接(link)路径。mkdirmkdir[-mp]目录名称-m:设置文件的权限喔!直接设置,不需要看默认权限(umask... 查看详情

学习笔记(二十二)——了解进程和线程(代码片段)

文章目录一、进程1.1、什么是程序1.2、了解进程1.3、进程的三种状态1.4、多进程二、线程2.1、了解线程2.2、了解多线程2.3、进程与线程的区别2.4、多线程实现2.5、线程锁2.6、全局解释锁(GIL)一、进程1.1、什么是程序程序是指令和... 查看详情

学习笔记android使用aidl实现进程间通信(代码片段)

一、编写服务端代码1、新建一个Book类,实现Parcelablepackagecom.licheng.android.weextest;importandroid.os.Parcel;importandroid.os.Parcelable;/***Createdbylichengon15/11/16.*/publicclassBookimplementsParcelablepubl 查看详情

linux学习笔记(代码片段)

Linux学习笔记(一)Author:akynazhBlog:akynazh.siteLinux开机CMOS是记录各项硬件参数且嵌入在主板上面的储存器BIOS则是一个写入到主板上的一个固件(固件就是写入到硬件上的一个软件程序)。这个BIOS就是在开机的时候,计算... 查看详情