热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

linux进程堆管理,linux进程管理

进程:运行中的程序假设我们要执行mkdir命令,首先我们的系统会去硬盘上读取mkdir这条命令的程序存放在内存中,然后cpu依次执行每条指

进程:运行中的程序

假设我们要执行mkdir命令,首先我们的系统会去硬盘上读取mkdir这条命令的程序存放在内存中,然后cpu依次执行每条指令,但是有些指令用户空间是无法执行的,比如我们的mkdir必然涉及到硬盘的操作,此时当指令执行到对硬盘的操作的时候,mkdir进程会通过系统调用,向内核申请操作,此时,mkdir进程从cpu上退出,内核进程占用cpu执行硬盘操作,完毕后继续回来执行mkdir进程。

但是内核进程操作完毕后怎么知道从哪里继续mkdir进程的指令呢?其实内核在内存为每个进程维护了一个数据结构叫task structure,纪录了进程各种属性信息,比如pid、ppid等等,内核更新task structure的过程叫保存现场,读取task  structure的过程叫恢复现场

我们知道程序有大有小,假如让它们自主分配内存的话将会导致很多问题,比如程序如何得知有哪些内存地址尚未被使用?等等。为了解决这个问题,内核引入线性内存的概念。默认每个进程都认为系统有4G内存空间,最底下的1G给内核用,进程彼此之间独立,认为当前系统上只有内核和进程自己本身两个进程,每个进程都可以申请3G内存,而这3G内存的地址则可以相同。

为了实现这个功能,内核把内存地址分成相同大小的单元,并在每个进程的task structure中额外维护有一张地址转换表,这个表记录进程线性地址与逻辑地址之间的转换关系,事实上,这张表还记录有额外的信息,看下图:

2907b6f279001f25a2258f7367f3381c.png

forbidden:此段是禁用的,这是内核自己腾出来的空间

program text:这段记录了程序的指令,而指令是不允许修改的,所以这也是只读段

.data和.bss:记录了程序的数据段

heap:堆,假设我们读取一个文件,我们必须把文件的内容读取到内存中,也就是这里的堆段,但是堆是逻辑概念,实际上的过程是内核发现堆增长了就查找空闲内存分配给堆,然后把文件读取进来

stack:栈,定义了本地变量,全局变量一般在.data里面定义,栈向下增长,堆向上,中间是程序Memory....libraries之间的共享库

我们知道Memory....libraries是进程间的共享库,那么当我们计算一个进程占用的空间大小的时候是否要把这段计算进去呢?计算与不计算都不是我们想要的结果,于是我们在计算进程占用内存大小的时候通常提供两个值rss(不计算)和vsz(计算)

注意:rss指的是常驻内存集,所以计算的是那些不被内存空间交换出去的数据大小(指令等等),vsz则计算的是包括共享库在内的内存占用空间。

类似地,进程的时间也有在cpu上运行的时间和挂钟时间(从进程生成到现在)的概念

进程的并行执行:

假设我们拥有多cpu或者cpu有多核心,那么我们的进程可否同时在两颗cpu上执行?答案是否定的,同一个进程同一时间只能在一个cpu上运行,它的指令有先后关系。但是可以在多个cpu上同时运行多个不同进程。

但是如果一个程序的是并行编程的结果的话,它的进程可以被分成多个线程流,而多个线程之间则可以在不同的cpu上执行,这就实现了同一进程在不同cpu上并行执行,比如数据库,它的查询操作可以做成多个线程流,因为彼此之间互不影响,这样做的其他好处是多个线程可以同享一些资源,比如数据库列表,如果采用多进程模型的话则需要打开多次,而采用多线程模型则只需打开一次作为共享资源,大大节约了内存空间。这样看来是不是多线程模型就一定比多进程模型好呢?答案是否定的,多进程模型对资源的操作是互相独立的,比如写操作(因为每个进程都有自己的内存空间,这里的写操作并不会马上影响磁盘上的数据)等等,而多线程模型则必须对资源进行分配给线程操作,给资源加锁,还要监控锁的释放等等。所以使用多线程还是多进程模型要根据实际情况来。

进程的状态:

2c99211677b90879d2afbc62f75561c7.pngstopped:停止态

ready:表示进程已经准备好,被内核调度即可执行

Executing:执行中

Uninterruptible:不可中断的睡眠态,这意味着计算此时内核把进程调度到cpu也不能执行,比如进程要到io请求数据,但是此时还没准备。

interruptible:可中断的睡眠态,类似ready,内核调度即可执行

zombie:僵尸态,进程结束,但是所占的内存无法释放,比如因为某个意外内核维护的这个进程的task structure丢失,导致内核无从得知进程占用了哪些物理内存。如果一个系统内有很多僵死进程的话,那么我们就可能出现明明类似内存4G明明只使用了2G却一直提示内存不足的情况

进程的优先级:

linux的优先级有0-139共140种,数字越小,优先级越高

100-139:用户可控制

0-99:内核调整

进程的优先级有高有低,一般我们需要先执行优先级高的进程,但是当我们的系统同时来了一大堆进程的时候,我们怎么快速地从中挑选出一个呢,如果按照一般的排队规则,系统光是排队就要消耗一大堆时间,这显然不是我们想要的,于是我们的linux内核2.6引入一种机制,linux按优先级给进程维持140个队列,每生成一个进程按优先级放入不同的队列中,当cpu时间到,从优先级高的队列往低的扫描,这样最多只需要扫描140次。

这里介绍几个算法常用的标准:

O:

O(1):不管队列长度为多少,挑选的时间都一样

O(n):随着队列长度增长,挑选时间成线性增长,即y=x

O(logn)

O(n^2)

O(2^n)

因此当我们想让某个进程优先处理,可以把它放在优先级较高的队列中。当一个进程的优先级比较高的时候意味着它拥有两个特性:

1.更多的cpu运行时间

2.更优先获得运行时间

linux可以通过修改进程的nice值来修改优先级,nice值越高,优先级越低,它们与队列的对于关系如下

nice值:

-20--19

100--139

普通用户仅能调大nice值

/proc 目录里面的数字对应每个进程的ID,进程对应的相关属性在里面修改

进程的分类:

跟终端相关的进程

跟终端无关的进程

进程相关命令:

ps:process status

sysV风格:需要加-

e:显示所有线程

l:长格式

f或F:更详细的信息

o:显示指定字段

bsd风格:不需要加-

a:所有与终端有关的进程

u:显示更详细的信息USER、%CPU等

x:所有与终端无关的进程

ps命令的stat字段:

D:不可中断的睡眠

R:运行状态

S:可中断的睡眠

T:停止

z:僵死

N:低优先级

+:前台进程

l:多线程进程

s:会话进程首进程

ps的COMMAN字段里面要是加[]代表这个是内核线程

pstree:显示进程树

pgrep:

pidof:查找运行中程序的id号

top:

cpu字段:

us:user space 用户占用的百分比

sy:system  内核占用...

ni:调整nice值后所占用的百分比

id:idle 空闲

wa:wait 等待

hi:hard interrupt硬件中断所。。

si:soft interrupt 软中断

st:stolen 偷走的,跟虚拟化相关

M:根据驻留内存大小进行排序

P:根据cpu使用百分比进行排序

T:根据累计时间进行排序

l:是否显示平均负载和启动时间

t:是否显示进程和cpu状态相关信息

m:是否显示内存相关信息

c:是否显示完整的命令行信息

q:退出top

k:终止某个进程

top

-d:指定延迟时长,单位是秒

-b:批模式

-n #:在批模式下,共显示多少批

进程间通信(IPC inter Process Communication)方式:

共享内存

信号:Signal

Semaphore:旗语

kill

l:显示所有信号

重要的信号:

1:SIGHUP 让一个进程不用重启就可以重读配置,并生效

2:SIGINT Ctrl+c 中断

9:SIGKILL 杀死一个进程

15:SIGTERM 终止一个进程(与9的区别,留时间给进程处理类似打开文件等处理,也是默认选项)

指定一个信号:

信号号码:kill -1

信号名称:kill  -SIGKILL 如:kill -SIGINT

信号名称简写: kill -KILL 如: kill  -INT

kill PID

kill %JOBID:终止某作业

killall COMMAND

killall指定信号的方法跟kill一样

调整nice值:

调整已经启动的进程的nice值:

renice NI PID

在启动时指定nice值:

nice -n NI COMMADN

bg和fg:

前台:占据了命令提示符

后台:启动之后释放命令提示符,后续的操作在后台完成

前台-->后台

Ctrl+z:把正在前台运行的作业送到后台

COMMAND &:让命令在后台运行

bg:让后台的停止作业继续运行

bg [[%]jobid]

jobs:查看后台的所有作业

作业号,不同于进程号,kill %2杀死的是作业号

+:命令将默认操作的作业

-:命令将第二个默认操作的作业

fg:把后台作业调回前台运行

fg [[%]JOBID]



推荐阅读
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了2020年计算机二级MSOffice的选择习题及答案,详细解析了操作系统的五大功能模块,包括处理器管理、作业管理、存储器管理、设备管理和文件管理。同时,还解答了算法的有穷性的含义。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 本文介绍了Python语言程序设计中文件和数据格式化的操作,包括使用np.savetext保存文本文件,对文本文件和二进制文件进行统一的操作步骤,以及使用Numpy模块进行数据可视化编程的指南。同时还提供了一些关于Python的测试题。 ... [详细]
  • MySQL数据库锁机制及其应用(数据库锁的概念)
    本文介绍了MySQL数据库锁机制及其应用。数据库锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,数据是一种供许多用户共享的资源,如何保证数据并发访问的一致性和有效性是数据库必须解决的问题。MySQL的锁机制相对简单,不同的存储引擎支持不同的锁机制,主要包括表级锁、行级锁和页面锁。本文详细介绍了MySQL表级锁的锁模式和特点,以及行级锁和页面锁的特点和应用场景。同时还讨论了锁冲突对数据库并发访问性能的影响。 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • Go语言实现堆排序的详细教程
    本文主要介绍了Go语言实现堆排序的详细教程,包括大根堆的定义和完全二叉树的概念。通过图解和算法描述,详细介绍了堆排序的实现过程。堆排序是一种效率很高的排序算法,时间复杂度为O(nlgn)。阅读本文大约需要15分钟。 ... [详细]
  • Week04面向对象设计与继承学习总结及作业要求
    本文总结了Week04面向对象设计与继承的重要知识点,包括对象、类、封装性、静态属性、静态方法、重载、继承和多态等。同时,还介绍了私有构造函数在类外部无法被调用、static不能访问非静态属性以及该类实例可以共享类里的static属性等内容。此外,还提到了作业要求,包括讲述一个在网上商城购物或在班级博客进行学习的故事,并使用Markdown的加粗标记和语句块标记标注关键名词和动词。最后,还提到了参考资料中关于UML类图如何绘制的范例。 ... [详细]
  • 本文介绍了一种轻巧方便的工具——集算器,通过使用集算器可以将文本日志变成结构化数据,然后可以使用SQL式查询。集算器利用集算语言的优点,将日志内容结构化为数据表结构,SPL支持直接对结构化的文件进行SQL查询,不再需要安装配置第三方数据库软件。本文还详细介绍了具体的实施过程。 ... [详细]
author-avatar
军校招生顾问天使
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有