一文搞懂supervisor进程管理
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一文搞懂supervisor进程管理相关的知识,希望对你有一定的参考价值。
参考技术A使用Python编写的进程管理程序supervisor来管理Python程序那是最合适不过了,supervisor基于CS架构,主要有以下两个组成部分:
基于ubuntu16.04,不同linux发行版均可使用包管理器进行安装,也可以使用源码安装和pip安装
pip安装方法
当前最新版本3.3.3,supervisord.conf 和supervisord.d文件夹已自动生成在/etc/supervisor/目录下。可以使用echo_supervisord_conf命令将配置信息重定向到制定目录,比如/etc
服务端启动
查看supervisord是否在运行
使用echo_supervisord_conf查看supervisord.conf可选的配置项:
详情如下
采用supervisord.conf和program.conf分离的方式进行本机进程管理,从默认配置中抽取出常用的supervisord模板
模板抽取基于以下考虑
从默认配置中抽取出常用的program模板
如果单独调整program日志大小和个数,则加入stdout和stderr四个参数,新的配置文件如下
一般情况下,不需要指定日志文件名称,默认的日志文件名称组成为
文件名称示例:concurrency_statistician-stderr---supervisor-OpZ5di.log.2
可以进入 supervisorctl 的 shell 界面,也可以直接在 bash 终端运行
关于program groups的命令使用较少暂不介绍
参考资料:
念念不忘,必有回响,小伙伴们帮我点个赞吧,非常感谢。
职场亮哥文章列表: 更多文章
一文彻底搞懂操作系统“内存管理“地址空间+重定位+虚拟内存+分页
想要更好的了解操作系统的"内存管理",心中要带着疑问去寻找答案;这样才能有一种探索未知的兴趣,而不至于迷失在枯燥的时间里。
🎈如今的计算机基本都支持运行比内存大的进程,众所周知,程序运行需要先装载到内存,它都装不下,那么它是怎么运行的呢?
🎈当你追寻各种流行的软件时,是否想过计算机在背后做了多少能努力?我运行一个程序,它怎么给我做到内存分配的呢?怎么做到各个软件之间的互不干扰呢?
1.初识物理内存
物理内存就是0~某个上限的地址集合
早期的存储器没有抽象,那么程序必须直接访问物理内存。如下面这条指令
MOV REGISTERR1 2000
🔔将位置为2000的物理内存的内容移到REGISTERR1中,但是这种情况只能有一个程序在运行;如果第一个程序在某个位置存储值之后,第二个程序又在该位置写入了一个新值,将擦除第一个程序写入的值,这两个程序就会直接崩溃。
❓ 如果直接使用物理内存,能不能运行程序呢?
当然可以,每次只能运行一个程序,当一个程序运行结束后,就把新的程序装入内存,覆盖前一个程序。
❓ 如果直接使用物理内存,能不能运行多个程序呢?
📚 这个是可行的,IBM的360早期模型有这种实现,它将内存划分为许许多多的块(每个块都是0~某个地址),为每个块分配一个4位的保护键。每个进程只能访问自身PSW(存有4位码)与保护键相同的内存,
这种虽然能够解决用户程序之间的相互干扰,但也有一个很大的缺陷:a程序运行之后,运行b程序,JMP20跳转到20的位置去执行了ADD指令,本来应该跳转到16400位置去执行SUB指令的。所以需要引入重定位技术
✨一句话总结:“如果要做到多个程序在内存中互不影响,需要解决两个问题:保护和重定位”。
2.存储器抽象——地址空间
🙄对于前面提到两个问题:" 保 护 和 重 定 位 保护和重定位 保护和重定位,前者大佬们提出了一个方案,即地址空间。
地址空间:进程用于寻址的地址集合。每个进程都有自己独立的地址空间。
❓有了地址空间,怎么解决一个进程的地址28对应的物理地址与另外一个进程地址28所对应的物理地址不同呢?一个比较简单的方法使用动态重定位。
2.1.动态重定位(基址寄存器+界限寄存器):
它将每个进程的地址空间映射到不同的物理内存,通常是在CPU内置两个寄存器:基址寄存器和界限寄存器,每一个进程访问内存取一条指令进行读或写数据,CPU在将虚拟地址发送到内存总线前,会自动加上基址寄存器的值。看下图:
如果,执行虚拟地址位20的指令,首先CPU会加上基址寄存器的值 (20+10240=10260),如果访问地址超过了界限,产生错误并终止访问。
❗采用这种基址寄存器+界限寄存器这种方式的缺点就是每次访问内存前都要进行加法运算。
那么内存超载之后,怎么解决的呢?最通用的两种方法是交换技术和虚拟内存
2.2.1交换技术
🎈顾名思义"交换技术"就是将内存中的数据保存到磁盘中,使用时再拿进来。
最开始只有进程A,之后进程B和进程C被加载到内存,当进程D被调用时,进程A别交换到磁盘。如果后面A进程再被调到内存时,它的地址就会发生变化,所以需要通过硬件对其地址进行重定位。 例如:前面提到的基址寄存器和界限寄存器就适用于这种交换技术。
🔔在交换过程产生了许多小的空闲区,通过将所有进程尽可能地向下移动,能够将这些小的空闲区合成一大块。该技术被称为”内存紧缩 ",通常不进行这个操作,因为它要花费大量CPU时间。
❓另外设想一下,如果某个进程内存不足,它就崩了吗?
大多数设计语言在堆中动态分配内存,当进程空间增长时就会产生问题,为例解决内存区域不足地问题,预留了一段空闲区供堆栈(向下)和数据段(向上)扩张。
❓操作系统如何做到对动态分配内存进行管理的呢?
2.2.2.空闲区内存管理
在动态分配内存时,操作系统必须进行管理,有两种跟踪内存的使用状况:位图和空闲区链表。
📜 (1)位图
✨分配单元的大小和内存的大小决定了位图的大小。
📜 (2)链表
对应上面的位图
为了更方便的回收内存,使用双链表将更为优秀。例如当某个进程结束,回收内存时,我们可以考虑如果该节点的pre指针指向的前一个块是否为空,如果是直接合并成一个新的块即可;next指向的也同样如此。
❓基于此链表的管理,那么为进程分配内存时,是分配大内存还是同样大的内存,如何做到效率最高?
(1)首次适配算法:沿着链表头部进行搜索,直到找到一个足够大的空闲区;将其分为两部分,一部分供进程使用,另外一部分是多余出来的内存形成一个新的空闲区。
(2)下次适配算法 :首次适配算法稍微修改就可以得到下次适配算法,首次适配算法每次都从头开始搜索,而下次适配算法,从上次搜索结束的位置作为起始位置。
(3)最佳适配算法 :搜索整个链表,找到最接近实际需要的空闲区进行分配;该算法能够避免拆分一个以后可能用到的空闲区。最佳适配算法会产生很多小的空闲区,可以使用最坏适配算法”,即每次都分配最大的空闲区。据说这不是个好主意。
此外科学家们还提出了很多优秀的注意…
👨🏽🔧说:我可以为进程和空闲区维护各自独立的链表,那么前面的四个算法速度都能得到提高
🎅🏽说:速度是能提高,但是内存释放时速度较慢;需要将回收的内存从进程链表中删除,然后插入到空闲区链表。
👨🏽🔧说:我还可以进行优化,可以不使用单独的数据结构存放空闲区链表,将这些信息保存在空闲区;每个空闲区的第一个字表示空闲区大小,第二个字指向下一个空闲区;比起使用空闲区链表少了一个字。
(4)快速适配算法 :有一个N项表,第一项指向4KB的空闲区链表头,第二项指向8KB的空闲区链表头…
❓当你的某个程序大到整个内存都无法存储下时,你怎么办?如果解决?
科学家们首先提出的是将这个程序分成多个段 , 将程序分段执行,将要运行的段可以将已经运行完段的内存内存进行覆盖; 这种方式虽然可行,但是非常复杂,据说很少程序员能够掌握!
2.3.虚拟内存
🎈虚拟内存的核心思想 : 每个进程都有自己独立的地址空间, 这个空间被分为多个块, 每一块称为页或者页面。这些页都有连续的地址范围,被映射到物理内存;并不是所有的页都在内存中才能运行程序;当程序运行时,如果发现缺少了某个页,操作系统会将其缺失的部分装入内存重新执行失败的指令。
2.3.1.分页(下面默认计算机都使用了虚拟内存技术)
大部分的虚拟内存都使用了一种称为分页的技术,看下面这条指令
MOV REG,1000 //将地址为1000的内存单元复制到REG中
由程序产生的地址称为虚拟地址,它们构成了一个虚拟地址空间;当计算机使用了虚拟内存之后,并不会将该虚拟地址直接送到内存总线上,而是被送到CPU中的MMU(内存管理单元),MMU将虚拟地址映射为物理内存地址。(下图虚拟地址每一块称为一页,物理内存每一块称为页框。上面虚拟内存提到的)
例如以下指令,它对应的物理地址为4096
MOV REG, 8192
上图中有的页面并没有被映射,当执行指令在没有映射的页面时,CPU就会发生缺页中断;操作系统之后会将一个很少使用的页框把它写入磁盘,将需要访问的页面读到刚才回收的页框中,修改映射关系,重新执行引起缺页中断的指令。
这特别像一个函数,参数是虚拟地址,返回的是物理地址。
它具体怎么实现的呢?
创作打卡挑战赛 赢取流量/现金/CSDN周边激励大奖以上是关于一文搞懂supervisor进程管理的主要内容,如果未能解决你的问题,请参考以下文章