进程的基本概念(上)

1、操作系统的基本概念
操作系统是用于控制控制和管理软硬件资源的计算机程序,是直接运行在裸机上的最基本的软件,任何其他软件都必须在操作系统的支持下才能够完成。
2、系统调用和库函数的概念
操作系统的定位:对下进行软硬件管理,对上提供良好的执行管理。
在开发角度,操作系统对外会表现为一个整体,但会暴露自己的部分接口,供上层使用,这部分由操作系统提供的接口叫做系统调用。
系统在使用上,功能比较基础,对用户的要求也相对较高,对部分系统进行封装,从而形成了库。
本质区别:库是系统调用的一层封装。
3、进程的基本概念,什么是进程?
进程是系统进行调度和资源分配的基本单位,是操作系统的结构基础。进程是程序的基本执行实体,程序是指令、数据及其组织形式的描述。程序加载到内存,就变成了一个进程。程序的一个执行实例。
4、进程的描述
进程的基本信息被放在一个叫做进程控制块(task_struct)的数据结构中,我们通常把它称之为PCB。task_struct是linux的一种数据结构,用一个链表存储每一个结构体,操作系统是管理者,进程是被管理者。
PCB中主要包含一下信息:
①标识符:用来区分与其他之间的唯一标识符
②状态:任务状态,进程退出码,退出信号
③优先级:相对于其他进程的优先级
④程序计数器:程序中即将被执行的下一条指令的地址
⑤内存指针:包括程序代码和进程相关数据的指针,还有其它进程共享内存块的指针,指向cup的指针,进程之间需要切换(上下文数据)
⑥上下文数据:进程执行处理器中的寄存器中的数据
⑦I/O状态信息:包括I/O请求,分配给进程的I/O设备,和被进程使用的文件列表
⑧记账信息:处理器处理时间总和,使用的时钟数总和
5、管理一个进程
进程加载到内存后,先对进程进行描述,再把这些进程组织起来,所有运行在系统里的进程都以task_struct链表的形式存在内核里。

6、有关进程常用的一些基本指令
ls /proc/
kill -9 进程id //杀死一个进程
ps aux //显示所有进程
ps axj //显示所有进程
ps aux | grep ‘进程ID’
ps aux | grep 文件名
ps -al //显示所有进程
kill -l //显示进程的所有信号
kill all 进程名 //杀死进程
7、通过系统调用获取进程标识符
进程:pid,通过getpid()获取
父进程:ppid,通过getppid()获取

pid_t getpid(void)  //进程ID
pid_t getppid(void)   //父进程ID
//pid_t相当于一个无符号整数

8、如何创建一个进程?
进程创建是操作系统执行程序的需要或者用户或进程要求创建一个新的进程。进程创建首先是在进程表中为进程建立一个进程控制块PCB,采用fork()系统调用将复制执行进程的PCB块到新的进程。
(1)fork()创建一个进程

 pid_t fork(void);
//返回值:子进程中返回0;父进程返回子进程ID,出错返回-1
//fork()之后,两个进程代码共享,数据各自私有一份,fork()之后两个进程的执行顺序毫不相干,执行顺序完全由调度器决定,fork()之后由父进程等待子进程退出

对fork()的理解:
①fprk()有两个返回值,原因是:
如果创建成功,父进程返回子进程
当fork准备返回时,fork()的工作已经执行完毕,调用return语句,创建的子进程也会调用return语句,父子进程共享这一句代码的PID,子进程返回0;如果创建失败,父进程返回-1,没有创建出新的子进程。
②fork之后,父进程和子进程共享代码,数据各自私有一份,同时子进程里面的很多PCB都继承了父进程,并不是刚开始父进程和子进程并不是刚开始就是分离的,而是采用了写时拷贝机制,只有需要写数据时才分离。
③fork()之后,父子进程交替进行
④fork之后:父子进程共享终端,当前路径,根路径;不共享进程ID
⑤fork之前只有父进程(bash进程),再由父进程创建一个子进程,fork()之后父子进程的执行顺序不确定,完全由调度器所决定
⑥父进程有多个子进程,子进程只有一个父进程
⑦fork()失败的原因
系统中有太多进程;实际用户的进程数超过了限制
(2)vfork()创建一个进程

 pid_t vfork(void);
// vfork()用于创建一个子进程,而子进程和父进程共享地址空间,也就是让父进程和子进程指向同一个结构体,fork()的子进程具有独立的地址空间

①vfork()保证子进程先运行
②在调用exec()或(exit)之后父进程才可能被调度运行
③调用vfork()后,父子进程共享虚拟地址空间
10.fork和vfork区别:
(1)fork是交替进行,vfork是父进程等待子进程结束了才运行
(2)fork执行写时拷贝,vfork不执行写时拷贝
(3)vfork的性能相对较好,vfork在任何一个系统上的实现都是有问题的,一般不使用
(4)vfork调用后要使用exit()函数或exec系列函数
10、进程的基本状态
R运行状态:并不意味着进程一定在运行中,进程要么在运行中,要么在运行队列中
S睡眠状态:进程在等待事件完成 (深度睡眠,浅度睡眠,可以被杀死)
D磁盘休眠状态:有时也叫不可中断睡眠状态,这个状态的进程通常会等待I/O的结束(工作状态,不可以被杀死)
T停止状态:发送SIGSTOP信号来终止进程,这个被暂停的进程可以通过发送SIGCONT信号继续运行
X死亡状态:任务列表里已经不存在这个进程
Z僵尸状态:当进程退出并且父进程没有读到子进程退出的返回码,就会产生僵尸进程,僵尸进程以终止状态保持在进程表中,并一直等待父进程读取退出状态码,只要进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入僵尸状态。
僵尸状态的危害
(1)读不到子进程的退出码,进程的退出状态就要一直持续下去,维护进程的退出状态是用数据进行维护的,属于PCB的一部分,Z状态不退出,PCB就需要一直维护
(2)父进程创建的子进程如果不进行回收,就会造成资源浪费
(3)内存泄漏
如何避免僵尸进程
(1) 让僵尸进程成为孤儿进程,由init进程回收;(手动杀死父进程)
(2) 调用fork()两次;
(3) 捕捉SIGCHLD信号,并在信号处理函数中调用wait函数;
11、孤儿进程
父进程如果提前退出,子进程就称为孤儿进程,孤儿进程被1号进程init进程领养,要有init进程进行回收,1号进程被操作系统领养。父进程退出后,被bash进程回收。
12、进程优先级
cpu资源分配的先后顺序,就是指进程的优先权,占cpu资源比较多,我们称之为cpu密集型进程,对cpu占用率低,喜欢占用IO的我们称之为IO密集型进程
这里写图片描述
PRI和NI:
PRI:即进程的优先级,PRI越小,优先级越高,默认是80,最小是60
NI:指进程可被执行的优先级的修正值,用来修改优先级数,通过修改NI(nice)值,对进程优先级进行调整,默认是0,最小是-20,对优先级进行修改时,每次都以80为基准值
更改进程优先级

nice -n -5 ./test  //开始执行程序时就指定nice值
renice -5 -p 5200   //PID为5200的进程nice值设置为-5

13、进程的特点
竞争性:系统中有许多进程,但是CPU资源只有少量,所以进程之间具有竞争属性
并发性:多个进程在一个CPU下采用进程切换的方式,在一段时间内多个进程都可以推进
并行性:多个进程在多个CPU下同时运行
独立性:多进程运行,需要独享各种资源,多进程运行期间互不干扰

猜你喜欢

转载自blog.csdn.net/wyn126/article/details/80053954