福州网站建设 网站设计 网站制作商务网站建设公

当前位置: 首页 > news >正文

福州网站建设 网站设计 网站制作,商务网站建设公,济南建设银行公积金网站,游戏后端开发需要学什么环境#xff1a;centos7.6#xff0c;腾讯云服务器Linux文章都放在了专栏#xff1a;【Linux】欢迎支持订阅#x1f339;相关文章推荐#xff1a;【Linux】冯.诺依曼体系结构与操作系统【Linux】进程理解与学习#xff08;Ⅰ#xff09;浅谈Linux下的shell–BASH前言章节…环境centos7.6腾讯云服务器Linux文章都放在了专栏【Linux】欢迎支持订阅相关文章推荐【Linux】冯.诺依曼体系结构与操作系统【Linux】进程理解与学习Ⅰ浅谈Linux下的shell–BASH前言章节介绍在前文中我们已经了解了进程的相关概念明白了OS管理进程实际上就是对进程对应的task_struct/pcb做相关操作但是实际上系统中存在的进程有很多我们可以输入指令ps -lA 来查看当前系统下的所有进程。而OS为了更高效的对进程进行管理不会对每个进程都面面俱到而是会将进程分为不同的状态这就好像OS为了更好的管理内存会将内存划分为不同的分区每个分区存放各自对应的数据类型比如栈区存放一些局部变量、静态区存放全局变量等从而来进行更好的管理。本次章节目标就是对进程的不同状态做相关介绍与深入了解。ps -lA查看系统下的所有进程部分阻塞与挂起阻塞在了解进程状态之前我们先来谈一谈阻塞与挂起的两个概念。所谓阻塞就是指进程因为等待某种资源就绪而导致的一种不推进状态。也就是我们常说的卡住了。这里简单举个例子就好比我们在下载一些东西时假如突然断网那我们的下载是不是就停住了然后等网络资源恢复后才可以继续进行下载。而这个停住的过程就是阻塞。实际上本质来说就是pcb此时本应被cpu调度执行下载但是因为网络资源突然断开此时pcb就会到网络资源对应的pcb队列中排队等待等到网络资源就绪并且排到它时它才会继续回到运行队列排队然后等待被cpu调度继续下载。分析图当然为了更直观的看到这种现象我们可以看下面这张图分析图2挂起挂起本质也是一种特殊的阻塞挂起是一种什么情况呢我们前文已经了解了进程内核数据结构pcb进程的代码与数据。而挂起实际上是指该进程的pcb没有被cpu调度然后占用了内存空间此时OS会将该进程的数据与代码放到磁盘中暂存等pcb被调度时再将代码和数据预加载到内存。★简单总结进程的pcb可以被维护在不同的队列阻塞进程因为等待某种资源而导致的不推进状态pcb会到某种资源的等待队列下排队等资源就绪时再被维护到运行队列等待调度cpu的调度一般是一种线性调度当然也存在因为进程优先级而导致的插队情况后面会讲挂起是一种特殊的阻塞pcb不被cpu调度os会将数据与代码暂存在磁盘等pcb进入运行队列等待调度时再将数据与代码预加载到内存。进程状态我们可以查看内核中的源码来看看进程的各种状态/*

  • The task state array is a strange bitmap of
  • reasons to sleep. Thus running is zero, and
  • you can test for combinations of others with
  • simple bit tests. */ static const char * const task_state_array[] { R (running), /* 0 / S (sleeping), / 1 / D (disk sleep), / 2 / T (stopped), / 4 / t (tracing stop), / 8 / X (dead), / 16 / Z (zombie), / 32 */ };运行状态RR表示该进程处于一种运行状态不过这里需要注意的是R状态表示的运行是指只要进程的pcb在运行队列下都是R并不是说一定是指在cpu上运行。我们看一下以下代码 #includestdio.hint main(){while(1){printf(hello world,pid:%d\n,getpid()); } return 0; } 运行结果与疑惑S表示的是可中断休眠状态为什么不是R状态呢实际上确实如我们所说我们的程序一直在运行但是cpu调度的速度实在是太快了我们很难捕捉到并且pcb相对于被cpu的调度时间其余99%的时间都用在了在外设显示器的等待队列中排队了。所以我们可以看到程序在不断打印数据在显示器但是却捕捉不到cpu调度pcb并执行的那一刻。不过我们假如将外设这个干扰给屏蔽了如下#includestdio.hint main(){while(1){}return 0;} 小总结一下只要处在运行队列下就是R状态所以我们有时可能会发现多个进程处于R状态也不足为奇这不是指它们同时被调度而是指它们都处在运行队列等待被cpu调度可中断休眠状态S正如上面的图片所示我们看到S状态是因为程序的pcb99%的时间都在外设的等待队列下排队而被cpu调度的那一刻我们捕捉不到。这里大家有没有发现休眠状态与我们的上面讲的阻塞状态一致阻塞就是指pcb不被cpu调度去某个资源的队列下等待资源就绪。事实上确实如此S状态的本质就是阻塞。pcb去某种资源的等待队列下排队等待资源就绪。至于说它是可中断休眠是因为我们可以通过ctrl c或者kill命令来结束该进程。可以这么来说 S状态就意味着进程在等待事件完成等待资源就绪并且这种状态是可以被我们使用指令来中断。可中断休眠不可中断休眠状态D所谓不可中断休眠状态说白了就是我们不可以使用kill、ctrl c等命令将进程中断我们只可以将电源关闭以此来结束进程但是这样做可能会造成数据的丢失等问题。这种状态一般很难看到暂停状态T暂停状态顾名思义就是让该进程暂停我们可以通过指令kill -19 pid的指令来暂停该进程。输入指令kill -18 pid可以使该进程继续运行。不过需要注意的是当恢复运行时此时的进程就处于后台进程我们用ctrl c结束不了用kill指令才可以中止进程关于前后台进程我会在后面的章节讲解。如下死亡状态X这个状态只是一个返回状态表示该进程已经彻底结束。我们不会在任务列表里看到这个状态。僵尸状态Z返回代码我们每一个进程结束时都会有一个退出码就好像我们写一个main函数时最后都会加上return 0return 0就表示该进程正常返回事实上就算我们不写return 0系统也会默认return 0这里的0就是该进程的返回代码。Linux下可以通过echo $?指令来查看该进程的返回代码vs下编译后的返回代码僵尸状态Z僵尸状态是指一个进程结束时它的返回代码没有被父进程读取那么该进程会一直处于一种僵尸状态等待父进程读取直到父进程读取返回结果后才彻底结束子进程。保持僵尸状态是为了让父进程读取该进程的返回代码而我们平常写的程序为什么结束后没有变成僵尸呢这是因为他们的父进程是bash不理解的可以看前面的章节有讲到bash下运行的程序的父进程都是bash而bash有回收机制所以我们写的程序运行结束后会被bash的回收机制回收。我们也就观察不到僵尸进程。不过我们可以写以下代码用fork创建子进程来观察僵尸状态 #includestdio.h#includeunistd.hint main(){//fork创建子进程pid_t idfork();if(id 0){//childwhile(1){printf(子进程pid:%d,ppid:%d\n,getpid(),getppid());sleep(1);}}else{//fatherwhile(1){printf(父进程pid:%d,ppid:%d\n,getpid(),getppid());sleep(1);}}return 0; } 此时我们kill -9 进程pid结束子进程观察子进程是否立马结束还是如我们所说维持僵尸状态等待父进程读取推出结果。通过以下运行结果可以发现子进程并不是直接退出。运行结果僵尸状态的危害如果一个进程处于Z状态假如它的父进程一直不读取该进程的退出码那么该进程会一直维持僵尸状态。而维护这个状态实际上就是维护这个数据该数据也属于进程基本信息保存在task_struct(PCB)中不仅占用了内存空间因为task_struct本身是一个结构体结构体都会有自己的大小并且维护pcb也是有一定的代价的。★简单总结一下R状态是指该进程的pcb处在运行队列而不是一定要在cpu上运行pcb被cpu调度运行的时间远远远远快于pcb在资源的等待队列下等待资源就绪的时间S与D的区别在于是否可以通过kill或者ctrl c来人为中止进程但两者本质都是阻塞kill -19 PID 暂停进程kill -18 PID恢复进程恢复后的进程属于后台进程不可ctrl c中止可以kill -9 PID中止暂停状态实际上也是阻塞要等待你发出指令继续运行僵尸状态是指子进程退出时退出结果没有被父进程读取子进程就会保持僵尸状态直到父进程读取返回结果才彻底结束。bash有回收机制所以我们写的程序运行结束后不会变成僵尸会被bash的回收机制回收僵尸进程会占用空间资源造成资源泄露具有一定的危害性具体避免方式以后再细谈孤儿进程我们上面讲了子进程退出时不会立马退出而是维持僵尸状态等待父进程读取退出结果。如果父进程是bash则会被bash的回收机制回收不会出现僵尸那么假如子进程正常运行父进程结束呢如下杀掉父进程发现子进程的父进程变成了1号这里我们来分析一下为什么父进程结束后不会出现僵尸呢答因为该父进程的父进程为bash退出结果被bash的回收机制回收了所以父进程没出现僵尸。为什么该父进程的子进程被1号进程领养了呢1号进程是什么1号进程实际上就是操作系统答父进程退出子进程被操作系统领养通过让子进程的父进程变成1号进程此时的子进程就是孤儿进程。被领养是为了读取子进程的退出结果。假如没有被领养的话子进程的退出结果就不会有人能拿到那么子进程就成了僵尸会一直存在造成内存泄漏。这是OS不允许的所以会让1号进程成为子进程的父进程从而拿到子进程的退出结果。end.生活原本沉闷但跑起来就会有风