目录
1Linux进程管理概述
程序是静态的,它是一些保存在磁盘上的指令的有序集合;而进程是一个动态的概念,它是一个运行着的程序,包含了进程的动态创建、调度和消亡的过程,是Linux的基本调度单位。
那么从系统的角度看如何描述并表示它的变化呢?在这里,是通过进程控制块(PCB)来描述的。进程控制块包含了进程的描述信息、控制信息以及资源信息,它是进程的一个静态描述。
内核使用进程来控制对CPU和其他系统资源的访问,并且使用进程来决定在CPU上运行哪个程序,运行多久以及采用什么特性运行它。内核的调度器负责在所有的进程间分配CPU执行时间,称为时间片(time slice),它轮流在每个进程分得的时间片用完后从进程那里抢回控制权。
解读:操作系统内核为了管理cpu和其他资源的访问,使用进程这一概念来管理。用进程来进行资源的调度分配!
2019-2-1更新:
费曼:到底什么是进程呢?今天去烧烤,准备了鱼,虾,贝克,羊肉,首先呢,这些食材的名称就是PID,把食材穿在铁丝上叫进程操作,因为烧烤架(CPU)有点小,所以要分考的先后顺序叫进程调度!
1.1进程标识符
OS会为每个进程分配一个唯一的整型ID,做为进程的标识号(pid)。进程除了自身的ID外,还有父进程ID(ppid),所有进程的祖先进程是同一个进程,它叫做init进程,ID为1,init进程是内核自举后的一个启动的进程。init进程负责引导系统、启动守护(后台)进程并且运行必要的程序。
进程的pid和ppid可以分别通过函数getpid()和getppid()获得。
解读:也就是说linux最开始的时候有一个祖先init进程,后续创建子进程,为其分配PID进程标识号。一个程序要想运行使用cpu等计算机资源,就必须分配要分配PID号,以便管理。
1.2进程的状态
进程是程序的执行过程,根据它的生命周期可以划分成3种状态。
1执行态:该进程正在运行,即进程正在占用CPU。
2就绪态:进程已经具备执行的一切条件,正在等待分配CPU的处理时间片。
3等待态:进程不能使用CPU,若等待事件发生(等待的资源分配到)则可将其唤醒。
1.3 Linux下的进程结构
Linux系统是一个多进程的系统,它的进程之间具有并行性、互不干扰等特点。也就是说,进程之间是分离的任务,拥有各自的权利和责任。其中,每个进程都运行在各自独立的虚拟地址空间,因此,即使一个进程发生了异常,它也不会影响到系统的其他进程。
Linux中的进程包含3个段,分别为“数据段”、“代码段”和“堆栈段”。
“数据段”放全局变量、常数以及动态数据分配的数据空间。数据段分成普通数据段(包括可读可写/只读数据段,存放静态初始化的全局变量或常量)、BSS数据段(存放未初始化的全局变量)以及堆(存放动态分配的数据)。
“代码段”存放的是程序代码的数据。
“堆栈段”存放的是子程序的返回地址、子程序的参数以及程序的局部变量等。
1.4Linux下的进程管理
启动进程:手工启动 调度启动
备注:
进程process:是os的最小单元 os会为每个进程分配大小为4g的虚拟内存空间,其中 1g给内核空间 3g给用户空间{代码区 数据区 堆栈区}
ps查看活动进程
ps –aux查看所有的进程
ps -aux| grep 'aa'查找指定(aa)进程
ps –ef 可以显示父子进程关系
top显示前20条进程,动态的改变
pgrep 'vi'查找进程
进程状态:执行 就绪 等待状态
ps -aux看%cpu(cpu使用量) %mem(内存使用量) stat状态{S睡眠 T暂停 R运行 Z僵尸}
vi a.c &(&表示后台运行),一个死循环,按ctrl+z可以把进程暂停,再执行[bg作业ID]可以将该进程带入后台。利用jobs可以查看后台任务,fg 1把后台任务带到前台,这里的1表示作业ID
kill -9 进程号表示向某个进程发送9号信号,从而杀掉某个进程 利用pkill a可以杀死进程名为a的进程
2进程的创建
Linux下有四类创建子进程的函数:system(),fork(),exec*(),popen()
2.1 system函数
#include <stdlib.h>
int system(const char *string);
system函数通过调用shell程序/bin/sh –c来执行string所指定的命令,该函数在内部是通过调用execve(“/bin/sh”,..)函数来实现的。通过system创建子进程后,原进程和子进程各自运行,相互间关联较少。如果system调用成功,将返回0。
#include <stdio.h>
#include <stdlib.h>
int main()
{
system("ls -l"); //system(“clear”);表示清屏
return 0;
}
此外,system函数后面的参数还可以是一个可执行程序,例如:system(“/home/cp/1”);如果想要执行system后面进程的时候,不至于对当前进程进行阻塞,可以利用&将/home/cp/1调到后台运行。
1 //2-1-1.c 2 #include<time.h> 3 #include<stdio.h> 4 void main() 5 { 6 printf("I am aready Sleep! "); 7 sleep(30); 8 printf("I am OK!"); 9 } 10 //2-1.c 11 #include <stdio.h> 12 #include <stdlib.h> 13 int main() 14 { 15 system("/home/alex/workspace/c/Linux_process_test/2-1-1&"); 16 printf("This is PS info "); 17 system("ps"); 18 return 0; 19 }
2.3. exec函数族
exec*由一组函数组成
int execl(const char *path, const char *arg, ...)
exec函数族的工作过程与fork完全不同,fork是在复制一份原进程,而exec函数是用exec的第一个参数指定的程序覆盖现有进程空间(也就是说执行exec族函数之后,它后面的所有代码不在执行)。
path是包括执行文件名的全路径名
arg是可执行文件的命令行参数,多个用,分割注意最后一个参数必须为NULL。