进程cpu资源的分配就是指进程的优先权。优先权高的进程有优先执行的权利。
加入NI值之后,PRI的值变成 PRI(new) = PRI(old) + nice;
当nice值为负值的时候,进程的PRI将变小,进程的优先级将变大,进程相对于原来的PRI值会更早被执行。当nice值为正的时候,相反的情况。
改变nice值的命令,命令有两个:nice,renice。
1、一开始执行程序就制定nice值:nice
1)nice -n -5 /usr/l ocal/mysql/bin/mysqld_safe &
2)语法:nice [-n<优先等级>][--help][--version]
3)参数
-n<优先等级>或-<优先等级>或-adjustment=<优先等级> ,设置欲执行的指令的优先权等级。等级的范围从-10到19,其中-20最高,10最低,只有root可以设置负数。
-help 在线帮助
-version 显示版本信息
2、调整已经存在的进程nice值:renice
renice -5 -p 5317 //PID为5317的进程NI(nice)值设置为-5
语法:renice[优先等级][-g<程序群组名称>...][-p<程序识别码>...][-u<用户名称>...]
小程序进行说明,代码如下:
上述程序子进程处于僵尸状态,后面会详细进行说明。
使用的nice命令:sudo nice -n -5 <可执行文件的路径>
使用的renice命令:sudo renice -10 -p <进程号>
如下图所示:
当进程执行时,它会被装载进虚拟内存,为程序变量分配空间,并把相关信息添加到task_struct中。
1、进程内存分为四个不同的段
a.文本段:包含程序的源指令。
b.数据段:包含静态变量。
c.堆:动态内存分区区域。
d.栈:保存局部变量,动态增长与收缩的段。
2、进程的两种创建方法:fork()和execve()
1)fork()创建:fork()创建子进程,子进程会得到父进程的数据段,栈段和堆区域的一份拷贝。子进程可以独立修改这些内存段。但是文本段是父进程和子进程共享的内存段,不能被子进程修改。
调用fork后会返回两个值或者一个值。两个值是指在调用成功的情况下,返回0表示子进程在运行,大于0的数表示父进程在运行,错误情况下就返回一个值,一个小于0的值。在创建成功的情况下,子进程执行返回0,是因为一个子进程只有一个父进程,所以无需知道它父进程的id,通过getppid()也就可以获取它的值,而父进程运行时,它需要知道它的至此执行对应的子进程是哪个,因为一个父进程可能会有不止一个的子进程,而且在父进程中也没有可以直接获得其子进程pid的库函数。
2)execve()创建:这个系统调用会销毁左右的内存段去重新创建一个新的内存段,execve()需要一个可执行文件或脚本做参数。
注:父子进程共享代码段,但是分别拥有自己的数据段和堆栈段
僵尸进程:
一个子进程在其父进程没有调用wait()或waitpid()的情况下退出。这个子进程就是僵尸进程。如果其父进程还存在而一直不调用wait,则该僵尸进程将无法回收,等到其父进程退出该进程将被init回收。
如下代码进行说明:
注:这里的父进程就是执行的main函数。子进程是父进程的副本,开始于fork函数。
一般来说,在fork之后的父进程先执行还是子进程先执行是不确定的(取决于内核的调度算法) 。可以决定谁先退出,一般都是让子进程先退出。
fork()函数:
fork()函数几乎完整地复制了父进程,子进程在许多属性上与父进程相同,执行的代码也完全相同,但是子进程与父进程则有着不同的PID编号、独立的数据空间和进程描述符。如果调用fork()函数成功,fork()函数有两个返回值,在父进程和子进程中返回的是不同的值,父进程中返回的是新产生子进程的PID,而子进程中则返回0。若fork()函数调用失败则返回-1。
下面通过一个例程来进一步理解掌握fork()函数,代码如下所示:
孤儿进程
一个父进程退出,而它的一个或多个子进程还在运行,那么子进程将成为孤儿进程。孤儿进程将被init进程(进程号1)所收养,并由init进程对它们完成状态手收集工作。
举例如下:
可以用此命令查看
while :; do ps -al | grep test3 ;sleep 1;echo "######################################";done