一、铺垫
1.在操作系统学科中,进程的状态分为三类:运行、阻塞、挂起
1.1运行态:凡是处于运行队列的所有进程,所处的状态被称为运行态(R状态);在运行队列里的含义是:我已经准备好了,可以随时被调度;在队列里或已经运行中的,都叫运行态
1.2如果只有单cpu,那么只有一个运行队列,俩cpu,就有两个运行队列;
2.一个进程只要把自己放到cpu上开始运行了是不是一直要执行完毕才把自己放下来?
答:不是!每一个进程都有一个叫做:时间片的概念;如果超过这个时间,就会强行从cup上扒下来,重新进入运行队列排队;所以在一个时间段内,所有的进程代码都会被执行;叫做并发执行;所以,就会存在把大量的进程从cpu上拿下来,放上去的动作——称之为进程切换;
3.阻塞状态:操作系统用一种数据结构类型来表示对应的硬件,并通过链表的形式链接起来,称为等待队列;处于等待队列里的进程,等着(键盘,磁盘等外设或软件输入数据)的过程称为阻塞状态,如果已经输入完数据,就会进入运行队列,这叫做唤醒;cpu会处理运行队列中的进程
3.1等待队列(阻塞队列)有n多个,系统里不下于上千个阻塞队列,进程内部也可能有阻塞队列来等待一个进程,可以把这个进程录入等待队列,等待某个设备;
4.挂起状态 一个进程,无论是运行状态还是阻塞状态,在没有cpu真正调度运行的那一刻,进程的代码和数据其实是在内存中处于空闲的(没有被使用的);那操作系统会将内核的PCB保留下来,与之相连的代码和数据会被保存到磁盘或外设中,相当于一个进程中,只有pcb在这里排队;代码和数据放在外设中;当代码就绪时,代码和数据会被重新换入到内存中,这两部分称为换出和换入;一个进程,只有pcb在排队,代码和数据放在外设等设备中,不在内存中,这个过程叫做挂起状态;
二、Linux的运行状态
"R (running)", /* 0 */ //运行状态
"S (sleeping)", /* 1 */ //浅度睡眠,可以被唤醒;与上方的阻塞状态相对应"D (disk sleep)", /* 2 */ //当服务器压力过大时,os会通过一定的手段,杀掉一些进程
//来起到节省空间的作用
//深度睡眠(磁盘睡眠)让进程在等待磁盘写入完毕期间,这个进程
//不能以浅度睡眠状态运行,即不能以S状态运行,
//源代码中规定D状态的进程,任何人都不能杀掉,包括操作系统;只能等待写完磁盘或写入失败的信号返回时,才会停止,或关机停止,有时关机都停不了,只能拔电源。不响应任何请求;不可以被中断,不可以被动唤醒;"T (stopped)", /* 4 */ //进程暂停,除了特殊信号外,一般信号就不接收了;或被其他进程控制只是把他停住了,不代表他在等待资源;
"t (tracing stop)", /* 8 */ //暂停进程的一种;大小t,暂时不分
"X (dead)", /* 16 */ //终止态:这个状态只是一个返回状态,瞬时性非常强;所以,你
//不可能任务列表里看到这个状态"
"Z (zombie)", /* 32 */ //僵尸态; //
三、Z状态(僵尸态)
1.一个进程已经退出,但是还不允许被OS释放,处于一个被检测的状态——叫做所谓的僵尸状态
2.子进程将事情办完了,父进程得知道,这事情成不成阿!父进程或OS得检测这个状态!让父进程或OS进行回收;(wait()、waitpid()这两个函数)
3.僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程(使用wait()系统调用),当没有读取到子进程退出的返回代码时就会产生僵死(尸)进程
4.僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码;所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态
5.必须要进行回收,否则会造成内存资源的浪费
僵尸态存在的意义
1.当写到http项目时,必须要保证主进程的项目,永远不会崩溃;
2.采用子进程的高度独立性;使得父子进程执行不同的代码;二者既有联系,又无联系(PCB、代码段、数据段、文件描述符、环境变量,都是相同的;两者也可以访问相同的资源),进程替换后,也只有代码段和数据段等部分不同;
3.即使子进程执行出错也不会影响父进程;而且,父进程还能通过wait()、waitpid()这两个函数,来确定子进程能否成功的完成任务,进行差错处理;