进程管理
今天我们开始讲进程管理的相关知识,进程是学习LInux系统的重要一节内容,不仅能更帮助我们了解LInux系统的原理组成,又能方便我们在平常运维工作中的管理工作,帮助我们故障排查.希望大家牢固的掌握进程知识.
以下是我们分享的内容:
-
概论
-
进程控制
-
进程管理工具
概论
程序执行:
多道程序的执行分为顺序执行和并发执行 程序顺序执行时的特征: 顺序性---程序执行的前驱图为单链条形 封闭性---程序运行时独占全机资源,资源的状态(除初始状态外)只有本程序才能改变它,程序一旦执行,其执行结果不受外界因素影响 可再现性---只要程序执行时的环境和初始条件相同,都可获得相同的结果 程序并发执行时的特征: 间断性---程序并发执行时由于共享资源以及完成一项任务时的相互合作造成的相互制约关系将导致并发程序具有“执行-暂停-执行”这种间断性的活动规律。 失去封闭性---多个并发程序共享系统中的各种资源 不可在现性
进程的描述
进程引入的目的:使程序并发执行并且可以对并发执行的程序加以描述和控制 进程控制块(Process Control Block,PCB) 用于描述进程的基本情况和活动过程,进而控制和管理进程。操作系统中最重要的记录行数据结构 进程实体=程序段+相关数据段+PCB 创建进程,实质上是创建进程实体中的PCB;而撤销过程,实质上是撤销进程的PCB。 进程的几种表述(定义): Process 进程是程序的一次执行 进程是一个程序及其数据在处理机上顺序执行时发生的活动 进程是具有独立功能的程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位 进程基本属性: 与进程相关的属性包括进程号(PID)、父进程号(PPID)、进程组号(PGID)。 1:进程号(PID) 进程号是系统维护的唯一标识一个进程的正数,进程号是无法再用户层修改的。在Linux系统中,系统的第一个用户进程为init进程,它的PID为1,其他的进程PID以此增加。 getpid函数 获取当前进程的PID 该函数在unistdd.h文件中声明 执行失败 -1 ,错误原因存储于errno中,pid_t类型其实就是int类型 2:父进程号(PPID) 任何进程(除init进程)都是由另一进程创建,该进程称为被创建进程的父进程,被创建的进程称为子进程,父进程号无法在用户层修改,父进程的进程号(PID)即为子进程的父进程号(PPID), 用户可以通过调用getppid函数来获取当前进程的父进程号(PPID),其函数定义在/unistd.h文件中。 3: 进程组号(PGID) 在Linux系统中,每个用户都拥有用户号(UID)和用户组号(GUID);和用户管理一样,进程也拥有自己的进程号(PID)和进程组号(PGID)。进程组是一个或者多个进程的集合。 它们与同一作业相关联,可以接受来自同一终端的各种信号,每个进程组都有唯一的进程组号,进程组号可以在用户层修改。 用户可以通过调用 getpgid()函数来获得指定的进程的进程组号(PGID)。其函数定义在 unistd.h文件中 如果执行失败则返回 -1 ,错误原因存储在errno中。 每个进程组都可以有一个组长进程,组长进程的进程组号等于其他进程号。但组长进程可以先退出,即只要在某个进程中有一个进程存在,则该进程组就存在, 与其组长进程是否终止无关。进程组的最后一个进程可以终止,或者装一道另一个进程组。 加入一个现有的组或者一个新的进程组的系统调用函数setpgid(),其声明如下: int setpgid(pid_t pid,pid_t pgid ); 进程用户属性: Linux 是权限有严格控制的操作系统,某个进程拥有的真实用户号(RUID)、真实用户组号(RGID)、有效用户号(EUID)、有效用户组号(EGID)信息。 在说道进程用户时,需要将文件的拥有者与拥有者组加以区别。 1:进程真实用户号(RUID) 对于进程而言,创建该进程的用户UID(执行此程序的用户)为此程序真实用户号RUID.可以通过getuid 函数来获取当前进程的真实用户号(RUID) 函数: extern _uid_t getuid(void) 此函数无参数,如果执行成功将返回当前进程的UID;如果执行失败则返回-1,错误原因存储在errno中。 2:进程有效用户号(EUID) EUID 主要用于权限检查。 3:进程用户组号(GID) 创建进程的用户所在的组号为该进程的进程用户组号(GID)。可以通过调用getgid()函数来获得当前进程的真实用户组号。 函数:extern _uid_t getgid(void) 此函数无参数,如果执行成功将返回当前进程的GID;如果执行失败则返回-1 ,错误原因存储在errno中。 4:有效进程用户组号(EGID) 一般情况下,EGID和GID 相同,但是,当某可执行文件设置了setgid位,那么任何用户(包括root用户)运行此程序时,其有效用户组号EGID该为文件的拥有者所在组,其原来EUID类似。 函数:extern _uid_t getegid(void) 此函数无参数,如果执行成功将返回当前进程的EGID;如果执行失败则返回-1 ,错误原因存储在errno中。 进程的特征: 动态性---进程实质是进程实体的执行过程。它由创建产生,由调度而执行,由撤销而消亡,有一定的生命周期 ↔︎ 程序只是一组有序指令的集合,是静态的 并发性---多个进程实体同存于内存中,且能在一段时间内同时运行 ↔︎ 程序(没有建立PCB)是不能参与并发执行的 独立性---进程实体是一个能独立运行、独立获得资源和独立接受调度的基本单位 ↔︎ 未建立PCB的程序都不能作为一个独立的单位参与运行 异步性---进程按各自独立的、不可预知的速度向前推进
进程的基本状态: 1.就绪状态Ready---进程已分配到除CPU以外的所有必要资源后,只要再获得CPU,便可立即执行。 多个就绪状态的进程按照一定策略排成一个队列->就绪队列 2.执行状态Running 3.阻塞状态Block---阻塞状态的进程排成一个队列->阻塞队列
4.创建状态和终止状态 1.创建状态---为了保证进程的调度必须在创建工作完成后进行,以确保对进程控制块操作的完整性 2.终止状态---首先是等待操作系统进行善后处理,最后将其PCB清零,并将PCB空间返还系统。进入终止状态后不能再执行, 但在操作系统中依然保留一个记录,其中保存此状态码和一些计时统计数据,供其他进程收集。 一旦其他进程完成了对其信息的提取之后,操作系统将删除该进程,即将其PCB清零,并将该空白PCB返还系统。 注意区分到达终止状态和就绪状态的条件差别
5.挂起操作: 进程被挂起意味着此时该进程处于静止状态。如果进程正在执行,它将暂停执行。若原本处于就绪状态,则该进程此时暂不接受调度。相对应的是激活操作。 挂起操作的引入 终端用户的需要---终端用户希望暂停程序以便研究其执行情况或对程序进行修改 父进程请求---父进程希望挂起某个子进程,以便考察和修改该子进程,或者协调个子进程间的活动 负荷调节的需要---当时是系统中的工作负荷较重以致影响实时任务的控制,挂起部分不重要的进程以便保证系统正常运行 操作系统的需要---操作系统希望挂起进程以便检查运行中的资源使用情况或者进行记账 引入挂起原语(Suspend)和激活原语(Active)操作后三个进程状态的转换 1. 活动就绪->静止就绪。未被挂起的就绪状态称为活动就绪状态(Readya),此时进程可以接受调度。该进程被Suspend后变为静止就绪状态(Readys),此时进程不再被调度。 2. 活动阻塞->静止阻塞。未被挂起的阻塞状态称为活动阻塞状态(Blockeda)。被Suspend后变为静止阻塞状态(Blockeds),该状态的进程在其所期待的事件出现后,将从静止阻塞变为静止就绪状态。 3. 静止就绪->活动就绪。处于Readys状态的进程若用激活原语Active激活后,转变为Readys状态。 4. 静止阻塞->活动阻塞。处于Blockeds状态的进程若用Active激活后,进程将转变为Blockeda状态。
引入挂起操作后五个进程状态的转换,相比于三进程状态,需要增加下列几种情况: 1. NULL->创建。一个新进程产生时,该进程处于创建状态。 2. 创建->活动就绪。在系统性能和内存允许情况下,完成对进程创建的必要操作后,相应的系统进程将进程的状态转换为活动就绪状态。 3. 创建->静止就绪。考虑到当前资源和性能要求,不分配给新建进程所需资源,主要是主存,相应的系统将进程状态转化为静止就绪状态,被安置在外村,不参与调度,此时进程创建工作尚未完成。 4. 执行->终止。进程完成任务或是出现无法克服错误,或是被OS或其他进程所中金,进入终止状态。
进程管理中的数据结构 1.用于管理控制的数据结构。每个资源和进程都设置了一个数据结构,用于表征其实体,称为资源信息表或进程信息表。四类:内存表、设备表、文件表和用于进程管理的进程表。 2.PCB的作用。使一个在多道程序环境下不能独立运行的的程序(含数据)称为一个能独立运行的基本单位,一个能与其他进程并发执行的进程。 A.作为独立运行基本单位的标志。有了PCB,就能在多到程序环境下独立运行,具有取得OS服务的权利。PCB是进程存在与系统的唯一标识 B.能实现间断性运行方式。进程因阻塞而暂停运行时,CPU现场信息被保存在被中断进程的PCB中。 C.提供进程管理所需要的信息。进程的整个生命期中,操作系统总是根据PCB实施对进程的控制和管理。 D.提供进程调度所需要的信息。PCB中提供了进程处于各种状态的信息。 E.实现与其他进程的同步与通信。PCB中有进程与用同步的信号量,用于实现进程通信的区域或通信队列指针等。 进程控制块中的信息 1.进程标识符。用于为一个标识一个进程。 A.外部标识符。方便用户(进程)对进程的访问,每个进程设置一个外部标识符。由创建者提供,字母、数字组成。还设置父进程标识以及子进程标识用于描述进程家族关系。用户标识用于只是拥有该进程的用户。 B.内部标识符。方便系统对进程的使用,赋予每一个进程唯一的数字标识符,是一个进程的序号。 2.处理机状态。由处理机的各种寄存器中的内容组成。处理及执行状态时,信息存放于寄存器中。进程被切换时,处理及信息保存在相应PCB,以便重新执行时能从断点继续。寄存器包括: A.通用寄存器,也称用户可视寄存器。用户可访问。暂存信息。 B.指令计数器。存放了要访问的下一条指令的地址。 C.程序状态字PSW,含有状态信息,如条件码、执行方式、中断屏蔽标志 D.用户栈指针,每个用户进程都有至少一条与之相关的系统栈,存放过程和系统调用参数及调用地址。指向该栈的栈顶。 3.进程调度信息。包括: A.进程状态。作为进程调度和对换时的依据。 B.进程优先级。 C.其他信息。与采用的调度算法有关。 D.事件。进程由执行态转换为阻塞态所等待发生的事件,即阻塞原因。 4.进程控制信息。 A.程序和数据的地址。内存或外存地址,以便再调度时寻址。 B.进程同步和通信机制。如消息队列指针、信号量等。全部或部分放于PCB。 C.资源清单。进程在运行期间所需的全部资源(CPU除外),还有已分配到该进程的资源清单。 D.链接指针。下一个进程的PCB首址。 进程控制块的组织方式 A线性方式。存于线性表。表的首址存放于内存的一个专用区域。实现简单开销小,是用于进程不多的系统。 B.链式方式。把相同状态进程的PCB通过PCB中的链接字链接成一个队列。如就绪队列、若干阻塞队列和空白队列。 C.索引方式。根据进程状态不同建立几张索引表。如就绪索引表、阻塞索引表。把索引表的内存首址存放在内存的一些专用单元。
进程控制
(操作系统内核)
将一些与硬件紧密相关的模块(中断处理程序),各种常用设备的驱动程序以及运行频率较高的模块(时钟管理、进程调度和公用的一些基本操作) 安排在紧靠硬件的软件层次中,使其常驻内存,被称为OS内核。目的:便于对这些软件进行保护,防止遭受破坏;提高运行效率。 处理机执行状态: 系统态,又称管态、内核态。权限高,执行一切指令,访问所有寄存器和存储区。 用户态,又称目态。的权限。执行规定指令,访问指定寄存器和存储区。 OS内核两大功能: 1.支撑功能.提供给OS其他模块所需的一些基本操作,支撑其工作。三个基本支撑功能: 中断处理。内核的最基本功能,整个操作系统活动的基础。需“有限处理”,以减少处理机中断时间。 时钟管理。基本功能。时间控制。 原语操作。原语(Primitive),有若干指令组成的,用于完成一定功能的一个过程,操作中的所有动作要么全做,要么不做,不可分割,不允许被中断。内核中可能有很多原语。 2.资源管理功能 进程管理。将运行频率高的模块或者因为多种功能模块所需要放入内核中以提高OS性能。 存储器管理。放入内核保证运行速度。 设备管理。因为设备管理与硬件密切相关,很大部分也都设置在内核中。 进程的创建 1.进程的层次结构。在UNIX中,创建进程的进程称为父进程,被创建的进程称为子进程。子进程进一步创建,形成一个进程的层次结构。子进程继承父进程所拥有的资源。子进程被撤销时应返还资源给父进程。进程不能拒绝其子进程的继承权。 2.引起创建进程的事件。一个进程区创建另一个进程的时间有四类: A.用户登录。系统内核位用户创建新进程。分时系统中,用户登录会为该用户建立一个进程并插入就绪队列中。 B.作业调度。系统内核位用户创建新进程。多到批处理系统,当调度某个作业时,便将他装入内存,为它创建进程并放入就绪队列。 C.提供服务。系统内核位用户创建新进程。用户提出请求,系统创建一个进程来提供用户所需的服务。 D.应用请求。由用户进程自己创建新进程。新进程和创建者进程并发运行。 3.进程的创建。创建新进程请求后,OS便调用进程创建原语Creat创建新进程: A.申请空白PCB,为新进程申请获得唯一数字标识符,并从PCB集合索取一个空白PCB。 B.微信进程分配器运行所需的资源。物理和逻辑资源,内存、文件、I/O设备、cpu时间等。从OS或父进程获得。 C.初始化PCB。初始化标识信息---系统分配标识符和父进程标识符放入PCB。初始化处理机状态信息。初始化处理及控制信息。 D.若果进程就绪队列能够接纳新进程,将新进程插入就绪队列。 进程的终止 1.引起进程终止的时间 正常结束。进程的任务已经完成。批处理系统用Holt指令表示运行已结束。分时系统用Logs off。 产生中断通知OS进程运行完毕。 异常结束。 越界错。程序访问的存储区越出进程的区域。 保护错。进程试图访问一个不允许访问的资源或文件或用不适当的方式访问。 非法指令。执行不存在的指令。错把数据当指令。 特权指令错。用户试图执行只允许OS执行的指令。 运行超时。进程执行时间超过指定的最大值。 等待超时。进程等待某事件时间超过指定的最大值。 算术运算错。进程执行一个被禁止的运算。如被零除。 I/O故障。I/O过程发生错误。 外界干预。进程应外界的请求而终止运行。这些干预有: 操作员或操作系统干预。如发生系统死锁,终止进程使摆脱死锁状态。 父进程请求。子进程已完成父进程所要求任务,父进程提出请求可结束子进程。 因父进程终止。父进程终止,所有子进程均终止。 2.进程的终止过程 A.根据被终止进程的标识符,从PCB集合中检索出该进程的PCB,从中读出该进程的状态。 B.若被终止进程处于执行状态,立即终止,并置调度标志位真,用于指示该进程被终止后应重新调度。 C.若该进程有子孙进程,均予以终止,以防不可控。 D.将被终止进程所有的全部资源或者换给父进程,或者还给系统。 E.将被终止进程(PCB)从所在队列一处,等待其他程序来搜集信息。 进程的阻塞与唤醒 1.引起阻塞和唤醒的事件 向系统请求共享资源失败。系统无足够资源。 等待某种操作的完成。 新数据尚未到达。 等待新任务的到达。 2.进程阻塞过程。使用阻塞原语block将自己阻塞。进程自身的主动行为。执行状态->停止执行->把PCB中状态改为“阻塞”->把PCB插入具有相同事件的阻塞队列->转调度程序重新调度,将处理机分配给另一就绪进程并进行切换,重新设置CPU环境。 3.进程唤醒过程。有关进程调用唤醒原语wakeup,等待该事件的进程唤醒。被阻塞进程从该事件的阻塞队列移出->将PCB状态改为“就绪”->将PCB插入到就绪队列。block和wakeup必须成对出现,否则进程将永久处于阻塞状态 进程的挂起与激活 1.挂起。suspend原语将指定进程或处于阻塞状态的进程挂起。检查被挂起进程的状态->活动就绪改为“静止就绪”,活动阻塞改为“静止阻塞”->把PCB复制到指定内存区域->若被挂起的进程正在执行, 则转向调度程序重新调度。挂起是进程自身或者系统或用户的干预行为(注意与阻塞行为的区别)。 2.激活。激活原语Active。将进程从外存调入内存->检查进程的现行状态,静止就绪改为“活动就绪”,静止阻塞改为“活动阻塞”。 抢占调度策略---每当有静止就绪进程被激活而插入就绪队列时,边检查是否有进行重新调度,优先级高的获得处理机使用权。
进程同步
1基本概念。 进程同步,是对多个相关进程在执行次序上进行协调,使并发执行的主进程之间能按照一定规则共享系统资源,并能很好地相互合作,是程序的执行具有可再现性。 间接相互制约关系。共享系统资源,如CPU、I/O设备等,是并发执行的程序相互制约,只能互斥访问。必须有系统实施统一分配,不允许用户进程直接使用。 直接相互制约关系。某些应用程序建立多个进程,这些进程将为同一项任务相互合作。进程的运行不受自身所控制,进程的异步性。 临界资源。属于临界资源的硬件有打印机、磁带机等,软件有消息缓冲队列、变量、数组、缓冲区等。 诸进程间应采取互斥方式,实现对这种资源的共享。一次仅允许一个进程使用的共享资源. 临界区。每个进程中访问临界资源的那段代码称为临界区。若能保证诸进程互斥地进入自己的临界区,便可实现诸进程对临界资源的互斥访问。 每个进程在进入临界区之前,先对欲访问的临界资源进行检查是否正被访问。如果此刻该临界资源未被访问,进程便可进入临界区对该资源进行访问,并设置它正被访问的标志; 如果此刻该临界资源正被某进程访问,则本进程不能进入临界区。临界区前加入进入区代码段,后面加入退出区代码段,用于标识临界区是否正被访问。多个进程中涉及到同一个临界资源的临界区称为相关临界区. 同步机制应遵循的规则 空闲让进 忙则等待 有限等待。进程有限时间内进入自己的临界区,以免“死等”。 让权等待。进程不能进入自己临界区,应立即释放处理机,以免陷入“忙等”。 2.硬件同步机制。测试和关锁。为防止多个进程同时测试到锁为打开的情况,测试和关锁必须连续不允许分开进行。 A.关中断。进入锁测试前关闭中断,完成锁测试并上锁后才打开中断。最简单的方法之一。缺点--滥用会导致严重后果;时间过长影响效率;不适合多CPU系统。 B.利用Test-and-Set指令实现互斥。初始lock为false,临界资源空闲。进程进入临界区前,先检查lock,若为false进入,对lock赋值true,其余进程无法进入。 C.利用Swap指令实现互斥。会陷入忙等。 3.信号量机制。 A.整形信号量。一个用于表示资源数目的整形量S。S大于等于零是代表可供并发进程使用的资源实体数,当S小于零时则表示正在等待使用临界区的进程数。原子操作wait(S)和signal(S)。P、V操作。S<=0,wait会陷入忙等。 B.记录型信号量。一个代表资源数目的整形变量value,一个进程链表指针list。若S的初值为1,表示只允许一个进程访问临界资源,此时信号量转化为互斥信号量,用于进程互斥。 C.AND行信号量。位进程一次性全部的分配给所需资源,待进程使用完后一起释放。 D.信号量集。 4 .信号量的应用 A.实现进程互斥。访问某临界资源,为资源设置互斥信号量mutex,初始值为1。mutex=1,两进程皆未进入需要互斥的临界区。mutex=0,一个进入,一个挂入阻塞队列。 mutex=-1一个运行,了一个因等待而阻塞在信号量队列中,需要被当前已在临界区运行的进程退出时唤醒。 B.实现前驱关系 5.管程。Monitors,也称为监视器。是一种程序结构,结构内的多个子程序(对象或模块)形成的多个工作线程互斥访问共享资源。这些共享资源一般是硬件设备或一群变量。 管程实现了在一个时间点,最多只有一个线程在执行管程的某个子程序。与那些通过修改数据结构实现互斥访问的并发程序设计相比,管程实现很大程度上简化了程序设计。 管程提供了一种机制,线程可以临时放弃互斥访问,等待某些条件得到满足后,重新获得执行权恢复它的互斥访问。管程一定能保证互斥,不必特地考虑保护临界区。
经典进程的同步问题
A.生产者消费者问题。也称有限缓冲问题。该问题是相互合作的进程关系的一种抽象。资源信号量empty和full,互斥信号量wait(mutex)和signal(mutex)。先执行对资源信号量的wait操作,再执行对互斥信号量的wait操作。否则引起死锁。这种方法叫信号灯法。 B.哲学家进餐问题。可以用来解释死锁和资源耗尽。
进程通信
进程通信的类型 A.共享存储器系统。基于共享数据结构的通信方式(效率低,低级通讯)。基于共享存储区的通信方式(高级)。 B.管道通信系统。借助共享pipe文件。互斥(读不写,写不读)、同步、确定对方已存在才可进行通信。 C.消息传递系统。不借助共享存储区或数据结构,利用封装了数据的message。用户透明化,应用最广泛。支持多处理机系统、否输出系统和计算机网络。高级。直接通信方式、间接通信方式。 D.客户机服务器系统。套接字、远程过程调用、远程方法调用。客户存根和服务器存根就好像各自的秘书一样。 消息传递通信的实现方式 A.直接消息传递系统。 B.信箱通信。进程间的通信需要某种中间实体(共享数据结构等)来完成。既可以实时通信,又可以非实时。私用邮箱(自己发收,别人只发),公用邮箱(都可发收),共享邮箱(指定发收)。
线程的基本概念
进程:使多个程序能并发执行,以提高资源利用率和吞吐量。
线程:减少程序在并发执行时所付出的时空开销,是OS有更好的并发性。
进程的两个基本属性:一个可拥有资源的独立基本单位;一个可独立调度和分派的基本单位。 线程:作为调度和分派的基本单位。线程仅拥有必不可少的、能保证独立运行的资源。 线程控制块TCB。线程标识符、一组寄存器、线程运行状态、线程专有存储区、信号屏蔽、堆栈指针。 进程就像一个大的仓储,线程就像快递员。整个仓储可以有很多快递员,共同完成任务。可并发执行。 线程的三种状态:执行状态、就绪状态、阻塞状态。 多线程OS中进程属性: * 进程是一个可拥有资源的基本单位 * 多个线程可并发执行 * 进程已不再是可执行的实体。线程是独立运行或调度的基本单位。 线程的实现方式: 1.内核支持线程KST。都在内核实现。多处理器系统中可多线程并行执行;一个受阻可运行其他线程;很小的数据结构和堆栈,切换快,开销小;可采用多线程技术。和用户线程切换时开销大。 2.用户级线程ULT。用户空间实现。不需转换到内核空间;调度算法可以进程专用;与平台无关。一个线程执行,其余只能等待;基于进程执行,进程阻塞,线程全阻塞。 3.组合方式。用户线程对内核线程。 多对一模型。开销小,效率高。一个线程受阻,整个进程受阻;每次只有一个线程能访问内核。 一对一模型。更好的并发功能。开销大,需要限制整个系统的线程数。 多对多。可并行,且效率高。 线程的实现: 1.内核支持线程的实现。建立PTDA任务数据区,内含多个TCB。内核线程的创建撤销与进程类似。调度切换分抢占式方式和非抢占方式。调度算法有时间片轮转法、优先权算法。 2.用户级线程的实现。 A.运行时系统(Runtime System)。用行驶系统中的用于管理和控制线程的函数驻留在用户空间,并作为用户级线程与内核间的接口。用户级线程在切换时不需转入和心态,由运行时系统的线程切换函数执行切换任务。加快了切换速度。 B.内核控制线程,轻型线程LWP。用LWP实现内核与用户级线程间的隔离,使用户级线程与内核无关。 程序启动时一般只有一个线程在执行,被称为“初始化线程”,用于创建新线程。 线程终止后并不立即释放所占资源,只有当进程中其他线程执行了分离函数后,才是资源才被其他线程利用。 线程(thread) 通常在一个进程中可以包含若干个线程,当然一个进程中至少有一个线程,不然没有存在的意义。线程可以利用进程所拥有的资源, 在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位,由于线程比进程更小, 基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统多个程序间并发执行的程度。 多线程(multiThread) 在一个程序中,这些独立运行的程序片段叫作“线程”(Thread),利用它编程的概念就叫作“多线程处理”。 多线程是为了同步完成多项任务,不是为了提高运行效率,而是为了提高资源使用效率来提高系统的效率。线程是在同一时间需要完成多项任务的时候实现的。 最简单的比喻多线程就像火车的每一节车厢,而进程则是火车。车厢离开火车是无法跑动的,同理火车也不可能只有一节车厢。多线程的出现就是为了提高效率。 二、说说区别 1、进程与线程的区别: 进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响, 而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮, 但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。 1) 简而言之,一个程序至少有一个进程,一个进程至少有一个线程. 2) 线程的划分尺度小于进程,使得多线程程序的并发性高。 3) 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。 4) 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。 5) 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。 三、说说优缺点 线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源的管理和保护;而进程正相反。同时,线程适合于在SMP(多核处理机)机器上运行,而进程则可以跨机器迁移。
简要理解进程
内核的功用:进程管理、文件系统、网络功能、内存管理、驱动程序、 安全功能等 Process:运行中的程序 (运行中的程序的一个副本,是被载入内存的一个指令集合) 进程ID( Process ID, PID)号码被用来标记各个进程 UID、 GID、和SELinux语境决定对文件系统的存取和访问权限, 通常从执行进程的用户来继承 存在生命周期 task struct: Linux内核存储进程信息的数据结构格式 task list:多个任务的的task struct组成的链表 进程创建: init:系统第一个进程(所有进程都依赖它 centos6系及以下) 父子关系 进程:都由其父进程创建, .COW 进程函数:fork()生成, clone()克隆
进程优先级
系统优先级:数字越小,优先级越高 范围: 0-139(centos 4,5) 各有运行队列和过期队列,两个队列根据进程的时间片互换,来 0-99(centos 6) 实时优先级: 范围:0-99 数字越大,优先级越高 nice值: (静态优先级) 范围: -20-19 值越小,优先级越高 映射到实际的优先级范围是100-139 1.优先进入cpu执行 2.更长的CPU处理时间 正常情况下,任何一个进程的优先级都是这个值,即使我们通过nice和renice命令调整了进程的优先级,它的取值范围也不会超出100-139的范围,除非这个进程是一个实时进程,那么它的优先级取值才会变成0-99这个范围中的一个。 普通用户只能调高nice值 管理员可以调高和降低nice值 ni: nice值 pri: priority,优先级 psr: processor, CPU编号 rtprio: 实时优先级 优先级继承 由于互斥,一个进程(设为A)可能因为等待进入临界区而睡眠。直到正在占有相应资源的进程(设为B)退出临界区,进程A才被唤醒。 可能存在这样的情况:A的优先级非常高,B的优先级非常低。B进入了临界区,但是却被其他优先级较高的进程(设为C)抢占了,而得不到运行,也就无法退出临界区。于是A也就无法被唤醒。 A有着很高的优先级,但是现在却沦落到跟B一起,被优先级并不太高的C抢占,导致执行被推迟。这种现象就叫做优先级反转。 出现这种现象是很不合理的。较好的应对措施是:当A开始等待B退出临界区时,B临时得到A的优先级(还是假设A的优先级高于B),以便顺利完成处理过程,退出临界区。之后B的优先级恢复。这就是优先级继承的方法。 3.Big O:时间复杂度,用时和规模的关系 O(1),O(logn),O(N)线性,O(N^2)抛物线,O(2^N) 进程相关概念: 进程内存: Page Frame: 页框,用存储页面数据,存储Page 4k LRU: Least Recently Used 近期最少使用算法,释放内存物理地址空间和线性地址空间 MMU: Memory Management Unit负责转换线性和物理地址 IPC: Inter Process Communication 同一主机上 signal shm: shared memory semophore 信号量,一种计数器 不同主机上: rpc: remote procedure call socket: IP和端口号 进程状态: Linux内核:抢占式多任务 进程类型: 守护进程: daemon,在系统引导过程中启动的进程, 和终端无关进程 前台进程:跟终端相关,通过终端启动的进程 注意:两者可相互转化 进程状态: 运行态: running 就绪态: ready 睡眠态: 可中断: interruptable 不可中断: uninterruptable 停止态: stopped,暂停于内存中,但不会被调度,除非手动启动 僵死态: zombie,结束进程,父进程结束前,子进程不关闭 什么是僵尸进程 一个进程在调用exit命令结束自己的生命的时候,其实它并没有真正的被 僵尸进程销毁, 而是留下一个称为僵尸进程(Zombie)的数据结构(系统调用exit,它的作用是 使进程退出,但也仅仅限于将一个正常的进程变成一个僵尸进程,并不能将其完全销毁) 僵尸进程是怎么样产生 在Linux进程的状态中,僵尸进程是非常特殊的一种,它已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集,除此之外,僵尸进程不再占有任何内存空间。它需要它的父进程来为它收尸。 如果他的父进程没安装SIGCHLD信号处理函数调用wait或waitpid()等待子进程结束,又没有显式忽略该信号,那么它就一直保持僵尸状态,如果这时父进程结束了,那么init进程自动会接手这个子进程,为它收尸,它还是能被清除的。 但是如果父进程是一个循环,不会结束,那么子进程就会一直保持僵尸状态,这就是为什么系统中有时会有很多的僵尸进程。系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程. 异步回收僵尸进程: fork()之后,子进程从父进程获取了一份拷贝,和父进程分别独立运行,僵尸进程的产生是因为父进程没有给子进程“收尸”造成的,又可以根据危害程度分为下述两类: 总体来说:当子进程结束之后,但父进程未结束之前,子进程将成为僵尸进程。 (1)当子进程结束之后,但父进程未结束之前,子进程将成为僵尸进程,父进程结束后僵尸被init进程回收。 (2)如果子进程结束了,但是父进程始终没有结束,那么这个僵尸将一直存在,而且随着exec,僵尸越来越多。
进程管理工具:
进程的分类:
CPU-Bound: CPU密集型,非交互 IO-Bound: IO密集型,交互
Linux系统状态的查看及管理工具:
pstree, ps, pidof,pgrep, top, htop, glance, pmap, vmstat, dstat, kill,pkill, job, bg, fg, nohup
pstree命令:
pstree - display a tree of processes
ps命令: process state
ps - report a snapshot of the current processes Linux系统各进程的相关信息均保存在/proc/PID目录下的各文件中 适用ps来查看进程信息 ps [OPTION]... 支持三种选项: UNIX选项 如-a BSD选项 如a GUN选项 如--help 默认显示当前终端中的进程 a 选项包括所有终端中的进程 x 选项包括不链接终端的进程 u 选项显示进程所有者的信息 f 选项显示进程的父进程 o 属性… 选项显示定制的信息 ,o必须跟字段名,个字段用逗号相隔: pid、 comm、 %cpu、 %mem、 state、 tty、 euser、 ruser 例: [root@wen-7 ~]# ps ao pid,tty,euser,ruser PID TT EUSER RUSER 1708 tty1 root root 59421 pts/0 root root 60726 pts/0 root root 常用组合: -ef -e: 显示所有进程 -f: 显示完整格式程序信息 常用组合: -eFH -F: 显示更完整格式的进程信息 -H: 以进程层级格式显示进程相关信息 常用组合:自定义 -eo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,comm axo stat,euid,ruid,tty,tpgid,sess,pgrp,ppid,pid,pcpu,comm 最常使用: ps aux| 其他命令 (grep) VSZ: Virtual memory SiZe,虚拟内存集,线性内存 虚拟分配给进程的内存量 RSS: ReSident Size, 常驻内存集 实际使用内存量 STAT:进程状态 R: running 运行 S: interruptable sleeping 睡眠可中断 D: uninterruptable sleeping 睡眠不可中断 T: stopped 停止 Z: zombie 僵尸 +: 前台进程 l: 多线程进程 N:低优先级进程 <: 高优先级进程 s: session leader,会话(子进程)发起者 [root@wen-7 ~]# ps axuf USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 2 0.0 0.0 0 0 ? S 9月06 0:00 [kthreadd] root 3 0.0 0.0 0 0 ? S 9月06 0:03 \_ [ksoftirqd/0] root 7 0.0 0.0 0 0 ? S 9月06 0:00 \_ [migration/0] root 8 0.0 0.0 0 0 ? S 9月06 0:00 \_ [rcu_bh]
按预定义的模式: pgrep
pgrep [options] patter -u uid: effective user,生效者 -U uid: real user,真正发起运行命令者 -t terminal: 与指定终端相关的进程 -l: 显示进程名 -a: 显示完整格式的进程名 -P pid: 显示父进程为此处指定的进程的进程列表 pgerp ssh : 查看进程中有ssh的字符串的进程 pgrep sshd | xargs -i kill -9 {} #将所有sshd进程退出 pgrep sshd | xargs kill -9 #同上 [root@wen-7 ~]# pgrep -u root 1 2 [root@wen-7 ~]# pgrep -U nobody 3290 [root@wen-7 ~]# pgrep -t tty1 1708 [root@wen-7 ~]# pgrep -P 1 719 742 753 [root@wen-7 ~]# pgrep -a 1 10 rcuob/1 19 rcuob/10 20 rcuob/11 21 rcuob/12
按确切的程序名称: /sbin/pidof
查看进程相关的id信息
[root@wen-7 ~]# pidof bash 59421 1403
uptime
显示当前时间,系统已启动的时间、当前上线人数,系统平均负载( 1、 5、 10分钟的平均负载,一般不会超过1)
系统平均负载:
指在特定时间间隔内运行队列中的平均进程数。
如果每个CPU内核的当前活动进程数不大于3的话,那么
系统的性能良好。 如果每个CPU内核的任务数大于5,那么这台机器的性能有严重问题。
如果linux主机是1个双核CPU的话,当Load Average 为
6的时候说明机器已经被充分使用了。
例: [root@wen-7 ~]# uptime 12:47:01 up 15:31, 1 user, load average: 0.00, 0.01, 0.05
top:进程监控工具
选项: -d #: 指定刷新时间间隔,默认为3秒 -b: 以批次方式 -n #: 显示多少批次 -i:忽略不显示僵尸进程 内置命令: k:结束某个进程 q:退出top r:调整指定进程的nice值 S: 开启/关闭累加模式 s:调整刷新的延迟时间(修改刷新时间间隔)
O: 指定要按照哪个字段进行排序 o:调整各个字段的先后顺序 按大写是向上移动 按小写向下移动 m:显示/隐藏内存信息 M: 根据内存使用率来排序 t:显示/隐藏CPU信息 P: 根据CPU的使用率进行排序 T: 根据时间/累加时间进行排序 c:显示完整的命令 W: 将top显示的信息保存到一个文件当中 排序: P:以占据的CPU百分比,%CPU
M:占据内存百分比,%MEM
T:累积占据CPU时长,TIME+
首部信息显示: uptime信息: l命令 tasks及cpu信息: t命令 Cpu分别显示: 1 (数字) memory信息: m命令 上栏位信息简介 us:用户空间 sy:内核空间 ni:调整nice时间 id:空闲 wa:等待IO时间 hi:硬中断 si:软中断(模式切换) st:虚拟机偷走的时间
下栏位信息简介 PID (Process Id):任务的进程ID PPID (Parent Process Pid):父任务的进程ID RUSER (Real User Name):任务的所有者真实名称 UID (User Id):任务所有者ID USER (User Name):任务所有者名称 GROUP (Group Name):任务所有者群组名 TTY (Controlling Tty):终端 PR (Priority):优先级 %CPU (CPU usage):CPU使用率 %MEM (Memory usage (RES)):内存使用率 S (Process Status):进程状态 TIME+ (CPU Time, hundredths):CPU时间,精确到秒
htop
htop命令:需从额外tar包安装,或rpm包安装 http://172.16.0.1/fedora-epel/7/x86_64 选项: -d #: 指定延迟时间; -u UserName: 仅显示指定用户的进程; -s COLUME: 以指定字段进行排序; 子命令: s: 跟踪选定进程的系统调用; l: 显示选定进程打开的文件列表; a:将选定的进程绑定至某指定CPU核心; t: 显示进程树
内存工具:
vmstat命令:虚拟内存信息
vmstat [options] [delay [count]] delay:延时#秒更新 count:刷新次数 例: [root@wen-7 ~]# vmstat 2 5 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 3 0 1464 129788 2188 678072 0 0 17 7 81 161 0 0 99 0 0 0 0 1464 129788 2188 678072 0 0 0 0 71 115 0 0 100 0 0 0 0 1464 129788 2188 678072 0 0 0 0 75 117 0 1 100 0 0 0 0 1464 129756 2188 678072 0 0 0 0 84 129 0 1 99 0 0 0 0 1464 129788 2188 678072 0 0 0 0 76 121 0 0 100 0 0 procs: r:等待运行的进程的个数,和核心数有关 b:处于不可中断睡眠态的进程个数(被阻塞的队列的长度) memory: swpd: 交换内存的使用总量 free:空闲物理内存总量 buffer:用于buffer的内存总量 cache:用于cache的内存总量 swap: si:从磁盘交换进内存的数据速率(kb/s) so:从内存交换至磁盘的数据速率(kb/s) io: bi:从块设备读入数据到系统的速率(kb/s) bo: 保存数据至块设备的速率 system: in: interrupts, 中断速率,包括时钟 cs: context switch, 进程切换速率 cpu: us:Time spent running non-kernel code sy: Time spent running kernel code id: Time spent idle. Linux 2.5.41前,包括IO-wait time. wa: Time spent waiting for IO. 2.5.41前,包括in idle. st: Time stolen from a virtual machine. 2.6.11前, unknown. 选项: -s: 显示内存的统计数据
pmap命令:进程对应的内存映射
pmap [options] pid [...] -x: 显示详细格式的信息; #pmap -x 1 另外一种实现: # cat /proc/PID/maps PID:进程PID
[root@wen-7 ~]# pmap 1 1: /usr/lib/systemd/systemd --switched-root --system --deserialize 21 00007fd608000000 164K rw--- [ anon ] 00007fd608029000 65372K ----- [ anon ] 00007fd60cc0e000 4K ----- [ anon ] 00007fd60cc0f000 8192K rw--- [ anon ] 00007fd60d40f000 4K ----- [ anon ] 00007fd60d410000 8192K rw--- [ anon ] 00007fd60dc10000 16K r-x-- libuuid.so.1.3.0 00007fd60dc14000 2044K ----- libuuid.so.1.3.0 00007fd60de13000 4K r---- libuuid.so.1.3.0 00007fd60de14000 4K rw--- libuuid.so.1.3.0 00007fd60de15000 224K r-x-- libblkid.so.1.1.0 00007fd60de4d000 2048K ----- libblkid.so.1.1.0 [root@wen-7 ~]# pmap -x 512 512: [events_power_ef] Address Kbytes RSS Dirty Mode Mapping ---------------- ------- ------- ------- total kB 0 0 0 [root@wen-7 proc]# cat /proc/1/maps 7fd608000000-7fd608029000 rw-p 00000000 00:00 0 7fd608029000-7fd60c000000 ---p 00000000 00:00 0 7fd60cc0e000-7fd60cc0f000 ---p 00000000 00:00 0 7fd60cc0f000-7fd60d40f000 rw-p 00000000 00:00 0 7fd60d40f000-7fd60d410000 ---p 00000000 00:00 0 7fd60d410000-7fd60dc10000 rw-p 00000000 00:00 0 7fd60dc10000-7fd60dc14000 r-xp 00000000 fd:01 67344992 /usr/lib64/libuuid.so.1.3.0 7fd60dc14000-7fd60de13000 ---p 00004000 fd:01 67344992 /usr/lib64/libuuid.so.1.3.0
glances命令: 系统监控工具 EPEL源
命令格式: glances [-bdehmnrsvyz1] [-B bind] [-c server] [-C conffile] [-p port] [-Ppassword] [--password] [-t refresh] [-f file] [-o output] 内建命令: a Sort processes automatically l Show/hide logs 显示/隐藏日志 c Sort processes by CPU% 由CPU % c类流程 b Bytes or bits for network I/O m Sort processes by MEM% w Delete warning logs 删除警告日志 p Sort processes by name 按名称排序过程 x Delete warning and critical logs i Sort processes by I/O rate 1 Global CPU or per-CPU stats d Show/hide disk I/O stats h Show/hide this help screen f Show/hide file system stats t View network I/O as combination n Show/hide network stats 查看/隐藏网络状态 u View cumulative network I/O s Show/hide sensors stats q Quit (Esc and Ctrl-C also work) y Show/hide hddtemp stats 显示/隐藏hddtemp统计数据 常用选项: -b: 以Byte为单位显示网卡数据速率 -d: 关闭磁盘I/O模块 -f /path/to/somefile: 设定输入文件位置 -o {HTML|CSV}:输出格式 -m: 禁用mount模块 -n: 禁用网络模块 -t #: 延迟时间间隔 -1:每个CPU的相关数据单独显示 C/S模式下运行glances命令 服务模式: glances -s -B IPADDR IPADDR: 指明监听的本机哪个地址 客户端模式: glances -c IPADDR IPADDR:要连入的服务器端地址
dstat命令:系统资源统计
如系统没有命令,需要安装软件 : # yum install dstat
dstat [-afv] [options..] [delay [count]] -c: 显示cpu相关信息 -C #,#,...,total -d: 显示disk相关信息 -D total,sda,sdb,... -g:显示page相关统计数据 -m: 显示memory相关统计数据 -n: 显示network相关统计数据 -p: 显示process相关统计数据 -r: 显示io请求相关的统计数据 -s: 显示swapped相关的统计数据 --tcp --udp --unix --raw --socket --ipc --top-cpu:显示最占用CPU的进程 --top-io: 显示最占用io的进程 --top-mem: 显示最占用内存的进程 --top-latency: 显示延迟最大的进程 [root@Wencx ~]# dstat ----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system-- usr sys idl wai hiq siq| read writ| recv send| in out | int csw 0 0 99 0 0 0|2385B 16k| 0 0 | 0 0 | 73 154 0 0 100 0 0 0| 0 0 | 780B 1938B| 0 0 | 122 223 0 0 100 0 0 0| 0 0 | 54B 66B| 0 0 | 79 159 [root@Wencx ~]# dstat -c ----total-cpu-usage---- usr sys idl wai hiq siq 0 0 99 0 0 0 0 0 100 0 0 0 1 1 98 0 0 0 0 0 100 0 0 0 [root@Wencx ~]# dstat -d -dsk/total- read writ 2385B 16k 0 72k [root@Wencx ~]# dstat -D /dev/sda dstat: /dev/sda does not exist ----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system-- usr sys idl wai hiq siq| read writ| recv send| in out | int csw 0 0 99 0 0 0|2385B 16k| 0 0 | 0 0 | 73 154 0 0 100 0 0 0| 0 0 | 108B 150B| 0 0 | 71 145 0 0 100 0 0 0| 0 0 | 54B 838B| 0 0 | 71 146 [root@Wencx ~]# dstat -g ---paging-- in out 0 0 0 0 0 0 [root@Wencx ~]# dstat -m ------memory-usage----- used buff cach free 712M 23.5M 152M 110M 712M 23.5M 152M 110M 712M 23.5M 152M 110M [root@Wencx ~]# dstat -n -net/total- recv send 0 0 54B 118B 54B 214B 780B 1636B^C [root@Wencx ~]# dstat -p ---procs--- run blk new 0 0 1.1 0 0 0 0 0 0 0 0 0 0 0 0^C [root@Wencx ~]# dstat -r --io/total- read writ 0.14 2.10 0 0 0 0 ^C [root@Wencx ~]# dstat -s ----swap--- used free 0 0 0 0 0 0 ^C [root@Wencx ~]# dstat --tcp ----tcp-sockets---- lis act syn tim clo 5 2 0 1 0 5 2 0 1 0^C [root@Wencx ~]# dstat --top-cpu -most-expensive- cpu process barad_agent 0.1 nginx: worker1.0 [root@Wencx ~]# dstat --top-io ----most-expensive---- i/o process crond 9648B 397B sshd: root@ 146B 208B sshd: root@ 78B 128B watchdog.sh 290k 16k secu-tcs-ag 217B 0 [root@Wencx ~]# dstat --top-mem --most-expensive- memory process mysqld 49.0M mysqld 49.0M mysqld 49.0M [root@Wencx ~]# dstat --top-latency --highest-total-- latency process nginx: worker 105 nginx: worker 130 nginx: worker 134 nginx: worker 168 ksoftirqd/0 167 nginx: worker 177 nginx: worker 444
kill命令:
向进程发送控制信号,以实现对进程管理 显示当前系统可用信号: kill -l
常用信号: man 7 signal 1) SIGHUP: 无须关闭进程而让其重读配置文件 2) SIGINT: 中止正在运行的进程;相当于Ctrl+c 9) SIGKILL: 杀死正在运行的进程 15) SIGTERM:终止正在运行的进程 18) SIGCONT:继续运行 19) SIGSTOP:后台休眠 指定信号的方法: (1) 信号的数字标识; 1, 2, 9 (2) 信号完整名称; SIGHUP (3) 信号的简写名称; HUP 按PID: kill [-SIGNAL] pid … -SIGNAL -u uid: effective user,生效者 -U uid: real user,真正发起运行命令者 -t terminal: 与指定终端相关的进程 -l: 显示进程名 -a: 显示完整格式的进程名 -P pid: 显示父进程为此处指定的进程的进程列表 按名称: killall [-SIGNAL] comm… killall和pkill是相似的,不过如果给出的进程名不完整,killall会报错。pkill或者pgrep只要给出进程名的一部分就可以终止进程。 $kill all -9 firefox 按模式: pkill [options] pattern pkill=pgrep+kill 杀死进程的方式 1. pkill方式 # pkill -u ttlsa 2. killall方式 # killall -u ttlsa 3. ps方式 ps列出ttlsa的pid,然后依次kill掉,比较繁琐. # ps -ef | grep ttlsa | awk '{ print $2 }' | sudo xargs kill -9 4. pgrep方式 pgrep -u参数查出用户的所有pid,然后依次kill # pgrep -u ttlsa | sudo xargs kill -9 例: 1.杀死 终端进程 [root@wen-7 ~]# ps aux| grep pts/1 root 69225 0.1 0.5 145416 5504 ? Ss 15:28 0:00 sshd: root@pts/1 root 69227 0.2 0.3 116692 3312 pts/1 Ss+ 15:29 0:00 -bash root 69273 0.0 0.0 112660 964 pts/0 R+ 15:29 0:00 grep --color=auto pts/1 [root@wen-7 ~]# kill 9 69225
调整进程优先级命令:
可通过nice命令调整进程的优先级,优先级的范围为100-139,分别对应 -20,19的阀值,进程启动时nice值为0, 其对应的优先级为120,nice数值越小优先级越高
nice命令
nice - run a program with modified scheduling priority nice [option] [COMMAND][ARGU….] [options] -n NICE : 指定nice值 #nice -n -5 htop #为115优先级启动htop 注意:nice值只有管理员可调
renic命令
renice - alter priority of running processes renice [-n] NICE PID -n NICE : 指定NICE值 #renice -n -3 5207 : 调整进程PID为5207的nice值为-3
原创文章,作者:wencx,如若转载,请注明出处:http://www.178linux.com/44371