Linux-进程描述(4)之进程优先级与进程创建执行
进程优先级
进程cpu资源分配就是指进程的优先权(priority)。优先权高的进程有优先执行权利。
权限与优先级
权限(privilege)是指在多用户计算机系统的管理中,某个特定的用户具有特定的系统资源使用权力,像是文件夹,特定系统指令的使用或存储量的限制。权限是有或没有的问题,而优先级则是在已经具有了权限而讨论权限大小的问题。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能。用“ps -l”指令查看系统进程:
注意到其中几个很重要的信息,PID(进程的代号)和PPID(父进程的代号)在前面的进程标识符里已经说过。UID代表执行者的身份。什么意思呐?比如说为什么持有身份证才可以在银行办理业务,因为身份证证明了你是中国合法公民,拥有合法权限,你以中国合法公民的身份在柜台办理业务;再比如学生可以在学校里上课、使用教学设施等等,那是他经过一定的手续成为本校的学生,他是以本校学生的身份在学校学习,而老师则以本校教师的身份在学校教书。当我们创建用户时,由我们为新建用户命名和设置密码,同时系统会为我们所创建的用户名关联一个号,就是所谓的用户uid,即用户的身份。通常用户的身份有普通用户和超级用户。进程uid与运行该进程的用户uid相同。PRI即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此值越小进程的优先级别越高,越早被执行。NI就是我们所要说的nice值了,其表示进程可被执行的优先级的修正数值。如前面所说,PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为:PRI(new)=PRI(old)+nice。
由此看出,PR是根据NICE排序的,规则是NICE越小PR越前(小,优先权更大),即其优先级会变高,则其越快被执行。如果NICE相同则进程uid是root的优先权更大。这样,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行。到目前为止,更需要强调一点的是,进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化。如果原来的PRI是50,并不是我们给予一个nice=5,就会让PRI变成55.因为是系统“动态”决定的,所以,虽然nice值是可以影响PRI,但最终的PRI仍要经过系统分析后才能决定。
修改进程优先级
修改进程优先级的命令主要有两个: nice,renice
1、一开始执行程序就指定nice值: nice
# nice -n -5 /usr/local/mysql/bin/mysqld_safe &
linux nice 命令详解
功能说明:设置优先权。
语 法: nice [-n <优先等级>][--help][--version][执行指令]
补充说明: nice指令可以改变程序执行的优先权等级。
参 数: -n<优先等级>或-<优先等级>或–adjustment=<优先等级> 设置欲执行的指令的优先权等级。等级的范围从-20-19,其中-20最高, 19最低,只有系统管理者可以设置负数的等级。
范例一: 用root给一个nice值为-5,用于执行vi,并观察该进程。
# nice -n -5 vi &
注意:
(1)一般用户的nice值为0~19;
(2)root可用的nice值为-20~19;
(3)一般用户仅可将nice值越调越高,如果本来nice为5,则只能调整到大于5的nice:
(4)一般用户仅能调整属于自己的进程nice值。
也就是说,要调整某个进程的优先级,就是“调整该进程的nice值”。
2、调整已存在进程的nice: renice
renice -5 -p 5200
#PID为5200的进程nice设为-5
linux renice 命令详解
功能说明:调整优先权。
语 法: renice [优先等级] [-g <程序群组名称>...] [-p <程序识别码>...] [-u <用户名称>...]
补充说明: renice指令可重新调整程序执行的优先权等级。预设是以程序识别码指定程序调整其优先权,您亦可以指定程序群组或用户名称调整优先权等级,并修改所有隶属于该程序群组或用户的程序的优先权。等级范围从-20–19,只有系统管理者可以改变其他用户程序的优先权,也仅有系统管理者可以设置负数等级。
参 数:
-g <程序群组名称> 使用程序群组名称,修改所有隶属于该程序群组的程序的优先权。
-p <程序识别码> 改变该程序的优先权等级,此参数为预设值。
-u <用户名称> 指定用户名称,修改所有隶属于该用户的程序的优先权。
范例二 : 将4222那个PID修改nice为-5。
也可以用top命令更改已存在进程的nice:
top
#进入top后按“r”–>输入进程PID–>输入nice值
进程创建执行
当进程执行时,它会被装载进虚拟内存,为程序变量分配空间,并把相关信息添到task_struct中。
进程内存布局分为四个不同的段:
• 文本段,包含程序的源指令。
• 数据段,包含了静态变量。
• 堆,动态内存分区区域。
• 栈,动态增长与收缩的段,保存本地变量。
这里有两种创建进程的方法, fork()和execve()。它们都是系统调用,但它们的运行方式有点不同。要创建几个一进程可以执行fork()系统调用。 然后子进程会得到父进程中数据段,栈段和堆区域的一份拷贝。子进程独立可以修改这些内存段。但是文本段是父进程和子进程共享的内存段,不能被子进程修改。
fork函数用于从已存在进程中创建一个新进程,新进程成为子进程,原进程成为父进程。这两个进程分别返回他们各自的返回值,其中父进程的返回值是子进程的进程号,子进程则返回0,因此返回值大于0标识父进程,等于0标识子进程。所以我们可以通过返回值来判定该进程是父进程还是子进程。fork函数创建新进程后的父子进程模型如下:
下面用一个简单程序来观察父子进程之间的运行过程:
该代码运行结果如下:
fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
1)在父进程中,fork返回新创建子进程的进程ID;
2)在子进程中,fork返回0;
3)如果出现错误,fork返回一个负值;
fork出错可能有两种原因:
1)当前的进程数已经达到了系统规定的上限,这时errno的值被设置为EAGAIN。
2)系统内存不足,这时errno的值被设置为ENOMEM。
创建新进程成功后,系统中出现两个基本完全相同的进程,这两个进程执行没有固定的先后顺序,哪个进程先执行要看系统的进程调度策略。
execve()函数创建一个新进程。这个系统调用会销毁所有的内存段去重新创建一个新的内存段。然后,execve()需要一个可执行文件或者脚本作为参数,这和fork()有所不同。注意,execve()和fork()创建的进程都是运行进程的子进程。
父进程fork一个子进程之后,在已存在的子进程中调用exec函数启动新的程序。新程序替换了当前进程的文本段、数据段、堆、栈。进程ID不改变。exec函数一共有七个,其中execve为内核级系统调用,其他(execl,execle,execlp,execv,execvp,fexecve)都是调用execve的库函数,我们可以使用7个函数中的任意一个。
函数定义: int execve(const char *filename, char *const argv[ ], char *const envp[ ]);
返回值: 函数执行成功时没有返回值,执行失败时的返回值为-1;
函数说明: execve()用来执行参数filename字符串所代表的文件路径,第二个参数是利用数组指针来传递给执行文件,并且需要以空指针(NULL)结束,最后一个参数则为传递给执行文件的新环境变量数组。
#include<unistd.h>
main()
{
char *argv[ ]={"ls", "-al", "/etc/passwd", NULL};
char *envp[ ]={"PATH=/bin", NULL}
execve("/bin/ls", argv, envp);
}
运行结果为:-rw-r--r-- 1 root root 1659 Feb 27 20:13 /etc/passwd
这与在bin目录下执行 ls -al /etc/passwd 所得到的结果是一样的。
fork是分身,execve是变身。
exec系列的系统调用是把当前程序替换成要执行的程序,而fork用来产生一个和当前进程一样的进程(虽然通常执行不同的代码流)。通常运行另一个程序,而同时保留原程序运行的方法是,fork+exec。
Linux-进程描述(4)之进程优先级与进程创建执行的更多相关文章
- linux进程学习-进程描述符,控制块
从数据结构的角度,进程用task_struct结构来描述,称为“进程描述符 (Process Descriptor)”或者“进程控制块(Process Control Block, PCB)”,其包含 ...
- 进程描述符(PCB)
进程描述符(PCB) 概述 CPU作为计算机的核心部件,我们当然希望它能一直工作,充分提高它的使用效率.对于上层软件来说,我们不可能直接去操控CPU(我们没这能力也没必要),因为操作系统是夹在计算机硬 ...
- Linux下1号进程的前世(kernel_init)今生(init进程)----Linux进程的管理与调度(六)
前面我们了解到了0号进程是系统所有进程的先祖, 它的进程描述符init_task是内核静态创建的, 而它在进行初始化的时候, 通过kernel_thread的方式创建了两个内核线程,分别是kernel ...
- Linux内核学习笔记(1)-- 进程管理概述
一.进程与线程 进程是处于执行期的程序,但是并不仅仅局限于一段可执行程序代码.通常,进程还要包含其他资源,像打开的文件,挂起的信号,内核内部数据,处理器状态,一个或多个具有内存映射的内存地址空间及一个 ...
- 《Linux内核分析》第六周 进程的描述与创建
[刘蔚然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] WEEK SIX(3 ...
- Linux下进程描述(1)—进程控制块
进程概念介绍 进程是操作系统对运行程序的一种抽象. • 一个正在执行的程序: • 一个正在计算机上执行的程序实例: • 能分配给处理器并由处理器执行的实体: • 一个具有普以下特征的活动单元:一组指令 ...
- Linux进程描述符task_struct结构体详解--Linux进程的管理与调度(一)【转】
Linux内核通过一个被称为进程描述符的task_struct结构体来管理进程,这个结构体包含了一个进程所需的所有信息.它定义在include/linux/sched.h文件中. 谈到task_str ...
- 《Linux内核分析》 第六节 进程的描述和进程的创建
<Linux内核分析> 第六节 进程的描述和进程的创建 20135307 张嘉琪 原创作品转载请注明出处 +<Linux内核分析>MOOC课程http://mooc.study ...
- 【Linux】进程优先级、进程nice值和%nice
用top或者ps命令会输出PRI/PR.NI.%ni/%nice这三种指标值,这些到底是什么东西?先给出大概的解释如下: PRI :进程优先权,代表这个进程可被执行的优先级,其值越小,优先级就越高,越 ...
随机推荐
- 1067: [SCOI2007]降雨量
1067: [SCOI2007]降雨量 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 2148 Solved: 554[Submit][Status] ...
- 关于如何介绍spring框架。
一.介绍Spring 1.Spring是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架. 2.概念:轻量级的IOC(控制反转或者依赖注入).AOP(面向切面或者面向方面) ...
- python自学基础1week
一.python老师介绍 二.为什么要学习python? 三.学习python有前途吗? 疗程1:语言基础 疗程2:网络编程 疗程3:web基础开发 疗程4:算法&设计模式 疗程5:pytho ...
- 整理:20个非常有用的Java程序片段
下面是20个非常有用的Java程序片段,希望能对你有用. 1. 字符串有整型的相互转换 String a = String.valueOf(2); //integer to numeric strin ...
- Ef+T4模板实现代码快速生成器
转载请注明地址:http://www.cnblogs.com/cainiaodage/p/4953601.html 效果如图,demo(点击demo可下载案例) 项目结构如图 T4BLL添加BLL.t ...
- iOS开发之CALayer
1. 概述 在iOS中,你能看得见摸得着的东西基本上都是UIView,比如一个按钮.一个文本标签.一个文本输入框.一个图标等等,这些都是UIView,其实UIView之所以能显示在屏幕 ...
- bash变量
bash中的变量的种类 根据变量的生效范围等标准 本地变量:生效范围为当前shell进程:对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效: 环境变量:生效范围为当 ...
- Jmeter-测试计划元件
打开Jmeter页面,默认显示测试计划和工作台: 1.测试计划: 用来描述一个性能测试,包含与本次性能测试所有相关的功能.也就说性能测试的所有内容是于基于一个计划的. 右键单击"测试计划&q ...
- 核心模块Path
核心模块Path 作用:用于帮助程序员来操作硬盘上的路径. 核心模块注意点:当引用核心模块的时候直接require('模块名'),不需要加任何路径或者后缀. Path中的常用API: dirname( ...
- 【Egret】中tree组件使用案例
Egret中tree组件使用案例,包含(文本过多时,自动换行功能) 下面代码结合http://bbs.egret.com/forum.php?mod=viewthread&tid=19028& ...