进程优先级
进程 cpu 资源分配就是指进程的优先权(priority)。优先权高的进程有优先执行权利。
权限与优先级。权限(privilege)是指在多用户计算机系统的管理中,某个特定的用户具有特定的系统资源使用权力,像是文件夹,特定系统指令的使用或存储量的限制。权限是有或没有的问题,而优先级则是在已经具有了权限而讨论权限大小的问题。配置进程优先权对多任务环境的 linux 很有用,可以改善系统性能。还可以把进程运行到指定的 CPU 上,这样一来,把不重要的进程安排到某个 CPU,可以大大改善系统整体性能。
查看系统进程
注意到其中几个很重要的信息,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,renice1、一开始执行程序就指定 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: renice1 renice -5 -p 52002 #PID 为 5200 的进程 nice 设为 - 5linux renice 命令详解功能说明:调整优先权。语法: renice [优先等级] [-g < 程序群组名称>...] [-p < 程序识别码>...] [-u < 用户名称>...] 补充说明: renice 指令可重新调整程序执行的优先权等级。预设是以程序识别码指定程序调整其优先权,您亦可以指定程序群组或用户名称调整优先权等级,并修改所有隶属于该程序群组或用户的程序的优先权。等级范围从 - 20–19,只有系统管理者可以改变其他用户程序的优先权,也仅有系统管理者可以设置负数等级。参数:-g <程序群组名称> 使用程序群组名称,修改所有隶属于该程序群组的程序的优先权。-p <程序识别码> 改变该程序的优先权等级,此参数为预设值。-u <用户名称> 指定用户名称,修改所有隶属于该用户的程序的优先权。
范例二 : 将 4222 那个 PID 修改 nice 为 - 5。
也可以用 top 命令更改已存在进程的 nice:1 top2 #进入 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 函数启动新的程序。exec 函数一共有六个,其中 execve 为内核级系统调用,其他(execl,execle,execlp,execv,execvp)都是调用 execve 的库函数。函数定义: int execve(const char *filename, char *const argv[], char *const envp[]); 返回值: 函数执行成功时没有返回值,执行失败时的返回值为 - 1。函数说明: execve()用来执行参数 filename 字符串所代表的文件路径,第二个参数是利用数组指针来传递给执行文件,并且需要以空指针 (NULL) 结束,最后一个参数则为传递给执行文件的新环境变量数组。
- 1#include 2 main() 3 {
- 4char * argv[] = {
- "ls",
- "-al",
- "/etc/passwd",
- NULL
- };
- 5char * envp[] = {
- "PATH=/bin",
- NULL
- }
- 6execve("/bin/ls", argv, envp);
- 7
- }
运行结果为:-rw-r--r-- 1 root root 1659 Feb 27 20:13 /etc/passwd 这与在 bin 目录下执行 ls -al /etc/passwd 所得到的结果是一样的。
fork 是分身,execve 是变身。
exec 系列的系统调用是把当前程序替换成要执行的程序,而 fork 用来产生一个和当前进程一样的进程(虽然通常执行不同的代码流)。通常运行另一个程序,而同时保留原程序运行的方法是,fork+exec。
来源: http://www.cnblogs.com/33debug/p/6734603.html