A: fork多创建了一个进程, 返回两个值是为了区分不同的执行流,执行不同的代码块; B: 其实fork之后的代码是父子进程共享的,fork函数既然是函数,且有返回值,那么内部一定有return...一般情况下,子进程和父进程也是共享数据的,但是一直共享数据也不现实,因为当我们要修改数据时,会把两个进程的数据都改了,这并不是我们想要的,但是重新开一块空间拷贝父进程的数据又有点浪费,所以linux就使用了一种叫写时拷贝的技术...阻塞: 阻塞可以说是处于一种等待的状态,大多会涉及到外设,外设的速度是毫秒级的,CPU的速 度是纳秒级的,相差6个数量级,所以一般涉及外设的访问,大多数会处在阻塞状态;... 处于阻塞状态的进程会被放到等待队列中,需要注意的是,内存中有非常多的等待队列,而 运行队列只有一个(有几个CPU就有几个运行队列)。...当进程退出并且父进程(使用wait()系统调用)没有读取到子进程退出的返回代码时就会产生僵死(尸)进程; 僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。
2.6 通过系统调用创建进程-fork初识 1. fork创建子进程 我们通过man fork了解到,fork是创建子进程的函数,但是当这个函数执行前,只有自己本身这个进程和他的父进程,执行之后,这个自己本身的进程就会变成子进程的父进程...即fork()之后,因为pid既可以是0也可以是1,会有父进程+子进程两个进程在执行后续代码(即两条路线去执行if和else if两个分支),fork()的后续代码,被父子进程共享,让父子进程执行后续共享代码的一部分...需要注意的是:我们所提到的这些拖拽,排队,不是进程本身的行为,而是他们PCB的行为! 因此所谓的进程的不同状态,本质就是进程在不同的队列中,等待某种资源!...5. t追踪暂停状态 对于追踪暂停状态,其实是一种特殊的停止状态,即进程在调试时就处于追踪暂停状态:(gdb) 6....暂停、追踪暂停等状态表现出来,而进程处于这些状态时是否会被调整为挂起状态,用户是不可得知的,因为操作系统没必要将挂起状态暴露给用户,用户也不关心一个进程是否会处于挂起状态。
注:并不是只有等待硬件资源进程才会处于阻塞状态,一个进程等待另一个进程就绪、一个进程等待某种软件资源就绪等都会处于阻塞状态。...,进程需要等待某种资源: 注:我们使用 ps axj 指令查看进程状态只能查看进程某一时刻的状态,而外设的速度是要远远低于CPU的,所以我们可以发现,虽然 process 也在执行加法运算,但是我们每次查询时进程基本都处于阻塞状态...僵尸状态就是进程在退出时等待父进程或者操作系统来读取退出状态代码,然后释放PCB的一种状态。...Z 状态,并且子进程后面还提示了 defunct (失效的,不再使用的),此时,如果父进程一直不对不对子进程进行读取,那么子进程就会变成僵尸进程。...(我们用的电脑一般都是并发,只有一个CPU) 七、进程切换 我们的笔记本只有一个CPU,代表着同一时刻只能有一个进程正在被运行,但是我们平时在使用电脑的时候,同一时间通常会运行着很多程序,并且这些程序都能被正常运行
fork函数的使用,以及写时拷贝机制的原理等,并且也学习了什么是僵尸进程,但是并没有具体讲到应如何处理僵尸进程,本次章节将对fork函数以及如何终止进程,还有僵尸进程的处理做更为详细的探讨。...当调用fork函数之前,父进程独立运行,调用fork之后,会执行两个执行流,即父子进程共享fork函数之后的代码。...,否则就算自己被kill掉了,也是处于一种僵尸状态(Z状态)存在着,直到父进程拿到自己的退出码以及退出状态,子进程才结束僵尸状态(bash的子进程由于bash有回收机制,所以不会出现僵尸进程)。 ...所谓阻塞式等待,就是父进程运行到waitpid该处的指令时,不会再往后继续执行指令,而是处于阻塞状态,等到子进程退出时,才会继续执行后面的指令。...所谓非阻塞式等待,就是父进程在执行waitpid指令时,假如子进程没有退出,则会给waitpid返回一个0,然后继续执行后面的指令。
3)守护进程:守护进程是一直运行的一种进程,经常在linux系统启动时启动,在系统关闭时终止。它们独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件。...0,并且返回都将执行fork之后的语句。...,而在 之后,父进程和新创建的子进程都在运行,子进程拷贝父进程的代码段,所以子进程中同样有 if(pid<0) printf("error in fork!")...调度程序在进行调度时,首先从处于“内存就绪”或“被抢占”状态的进程中选择一个其优先数最小(优先级最高)的进程。...2、是不是有更高优先级的进程在活动队列中等待调度?如果任何一种情况成立,就把则当前进程的执行状态终止,放到等待队列中,换当前在等待队列中优先级最高的那个进程执行。
fork( )只是将父进程的用户级上下文拷贝到新进程中,而exec( )系列可以将一个可执行的二进制文件覆盖在新进程的用户级上下文的存储空间上,以更改新进程的用户级上下文。...用fork( )建立子进程,然后在子进程中使用exec( ),这样就实现了父进程与一个与它完全不同子进程的并发执行。...(3)若未找到处于“僵死状态”的子进程,则调用进程便在可被中断的优先级上睡眠,等待其子进程发来软中断信号时被唤醒。...如果调用进程在执行exit( )时,其父进程正在等待它的终止,则父进程可立即得到其返回的整数。...四、分析原因 程 序在调用fork( )建立一个子进程后,马上调用wait( ),使父进程在子进程结束之前,一直处于睡眠状态。
结合目前,我们得出一个小结论,只有父进程执行 fork() 之前的代码,fork() 之后的代码,父子进程都要执行。 那么我们为什么要使用 fork() 创建子进程呢?...我们首先需要知道,如果一个函数执行到 return,它的核心工作已经完成了,但是 fork() 之后,代码共享,当代码执行到 return 的时候,return 也是代码,是代码就要进行共享,所以当父进程被调度时...这个状态是专门针对磁盘来设计的,而且处于当前进程状态是不可被终止的,操作系统也没有资格!因为访问磁盘的速度很慢,必须要等待磁盘做出响应。...Z(zombie) - 僵尸进程 僵尸状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程(使用wait()系统调用,后面讲)没有读取到子进程退出的返回代码时就会产生僵尸进程。...僵尸进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。 所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态。
2 进程创建 2.1 fork函数初识 在linux中fork函数时非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。...父进程与子进程同理,父进程为了便于管理子进程,所以fork函数会返回对应子进程的pid。 2.3 写时拷贝 通过图解可以很好理解写时拷贝。...父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息 也就是说,任何进程在退出时都要被父进程进行等待,不然子进程处于僵尸进程就会造成内存泄漏!!!...,并且会存在一段时间的窗口期,此时子进程处于僵尸进程: 在这个父进程等待的过程中,父进程一直在等待子进程的退出,处于阻塞等待状态。...父进程本质是等待某种软件条件就绪,那么如何理解阻塞等待子进程呢??? 就是把自己列入等待队列,把状态列入不运行状态,等待子进程(类似scanf 的阻塞)。
僵尸进程产生的原因:每个Linux进程在进程表中都有一个进入点,内核执行该进程时,使用到的一切信息都存入在进程点。我们可以使用ps命令来查看进程状态。...0; } 运行结果如下: 当子进程打印完I am son之后,子进程结束,并且使用了_exit进行了退出。...那么可以使用signal函数为信号SIGCHLD注册处理函数。当子进程结束之后会发出SIGCHLD信号,然后父进程会收到该信号,可以在信号处理函数中使用wait函数来回收子进程。...当他为0时,和wait()一样,阻塞父进程,等待子进程退出。当他取值为WNOHANG时,如果没有已经结束的子进程则马上返回,返回值为0。最常用的就是这两个。...当我们知道系统有僵尸进程出现之后,使用ps aux | grep Z命令来查看处于僵尸状态的进程。 可以看到有一个僵尸进程。
-fork初识 运行 man fork 认识fork fork有两个返回值 父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝) fork 之后通常要用 if 进行分流 #include <stdio.h...(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里 S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠) D磁盘休眠状态...当进程退出并且父进程(使用wait()系统调用)没有读取到子进程退出的返回代码时就会产生僵尸进程僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。...,因为他要告诉父进程,你如果父进程如果一直不读取,那子进程就一直处于Z状态。...,也就是子进程先修改,完成之后,父进程再读取 g_val=100; printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val
当进程退出并且父进程(使用wait()系统调用,后面讲) 没有读取到子进程退出的返回代码时就会产生僵死(尸)进程 僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。...1.2 为什么会存在僵尸状态 Linux进程中,当一个进程死亡时不会立刻销毁,而是要等待我们读取死亡信息后才会死亡!...因此我们可以知道:当进程退出但是还没被读取退出信息时处于僵尸状态 PCB释放: 当一个进程在退出的时候,退出信息会由OS写入到当前退出进程的PCB中,可以允许进程的代码和数据空间被释放,但是不能允许进程的...可父进程如果一直不读取,那子进程就一直处于Z状态!...开个玩笑,孤儿进程是父进程在子进程退出之前就先退出了,此时的子进程就称为“孤儿进程” 但是前面刚刚讲过一个进程在死亡时,PCB的死亡信息必须被读取后,才会释放PCB,但是如果父进程已经退出了,子进程的
fork 调用成功时,在父进程中返回子进程的 PID,而在子进程中返回 0。 如果 fork 调用失败,则返回一个负数,表示错误。...在 fork 调用后,父子进程都会继续执行 fork 调用之后的指令,但是它们会在不同的地址空间中运行,即它们各自拥有独立的内存空间。...例如处于运行状态的进程会被分配 CPU 时间片并执行指令;处于阻塞状态的进程会被放入阻塞队列中等待某种事件的发生,如 I/O 操作的完成 运行 一个 CPU 一个运行队列: 在操作系统中,为了有效地管理进程的调度和执行...阻塞 当进程需要等待某种事件发生时,例如等待 I/O 操作完成或等待某个信号,它会进入阻塞状态。在阻塞状态下,进程暂时停止执行,让出 CPU 给其他可以执行的进程。...进程进入等待队列确实意味着它被链接到底层设备。这样,当设备就绪并且有了相应的数据或事件时,操作系统可以从等待队列中找到相应的进程,并唤醒它们以继续执行。
此外还可以通过调用fork函数创建子进程,子进程和父进程共享fork之后的代码,可以采用对fork返回值进行判断的办法来让父子进程分别执行后续代码的一部分。...首先来看使用exit时的结果: 再来看看使用_exit时的结果: 可以看到两者之间最大的区别就是exit在程序结束时会将缓冲区内的数据刷新出来,但是_exit却不会将缓冲区刷新出来。...因此可以得到一个结论:缓冲区并不在内核空间当中,而是一个用户级的缓冲区。 三.进程等待 当子进程退出以后,如果父进程一直不回收子进程的资源,那么子进程就会处于僵尸状态,会造成内存泄漏的问题。...在他下楼我们挂掉电话之前我什么也干不了,只能一直保持着和他打电话的状态。 这种舔狗式的等待方式就是阻塞式等待,但是父进程一直保持着等待状态,直到子进程运行完毕父进程再去回收子进程的资源。...4.非阻塞式等待 在非阻塞等待中,父进程会采用轮询的方式检测子进程的状态,如果子进程没有退出,那么父进程就去继续做自己的事,如果在某一次询问中,父进程发现子进程已经结束了,那么父进程就会去回收子进程的资源
(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里 S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠(interruptible...命令 休眠状态---进程在等待资源就绪 kill -19 暂停 kill -18 继续 T是比较纯粹的暂停,t是由于被追踪而暂停下来 3.3 Z(zombie)-僵尸进程 僵死状态(Zombies)是一个比较特殊的状态...当进程退出并且父进程(使用wait()系统调用没有读取到子进程退出的返回代码时就会产生僵死(尸)进程 僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码 所以,只要子进程退出,父进程还在运行...可父进程如果一直不读取,那子进程就一直处于Z状态?是的!...3.5 孤儿进程 父进程如果提前退出,那么子进程后退出,进入Z之后,那该如何处理呢?
,数据各自开辟空间私有一份(采用写时拷贝:进行写入时触发拷贝) fork()返回值: 对于父进程,如果创建成功返回子进程的pid,否则返回负数 对于子进程返回0(成功创建) 注意:...的前一刻,其主体任务全部完成,也就是子进程成功创建,此时父子进程代码共享,数据各有一份(写时拷贝),在返回时发生写实拷贝,对于父进程的ret则是返回的子进程的pid,对于子进程的ret则是返回的0...当进程退出并且父进程(使用wait()系统调用)没有读取到子进程退出的返回代码时就会产生僵死(尸)进程 僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码 即只要子进程退出...,所以必须被维持下,以此等待父进程获取其退出信息及任务状态,进行下一步打算 僵尸进程的危害: 父进程如果一直不读取,那子进程就一直处于Z状态,而维护退出状态本身就是要用数据维护,也属于进程基本信息...示例: 为什么PRI要有基准值以及NI具有范围: 避免过高或者过低的优先级出现,保证可控并且竞争的相对公平,提高效率 便于运算,不用再读取优先级信息,并且实现简单 进程退出CPU的可能
,这样在main()函数中调用fork函数时,从fork返回的两个执行流就会分别执行main()调用fork之后的代码,因此我们之前所了看到的两个结果就是父子进程对应的执行流所造成的。...sleep10秒,而父进程sleep15秒,这样当子进程运行完毕exit时,父进程在子进程结束的5s内不会回收子进程,这就造成子进程变成Z(僵尸)状态,当5s之后,父进程就会通过wait回收子进程,ret...那么这段代码我们编辑完成之后赋值ssh渠道进行观察进程的状态: 一开始右侧执行脚本,观察状态,同时左侧运行mytest,我们发现当子进程正在执行时,子进程和父进程都处于S+状态,当子进程执行完毕,没有被父进程回收时的那...5秒,子进程就变成了Z+状态,当父进程执行时,通过调用wait将子进程回收,子进程就结束了,最后的5秒只剩下父进程处于S+状态。...即我们可以总结成一张图: 上述的过程我们也再总结一下: 让OS释放子进程的僵尸状态 获取子进程的退出结果(如果子进程不结束,父进程就会一直处于阻塞等待,等待子进程退出) 2.
一、再识fork() 对于fork我们是比较熟悉的了,现在我们可以在来看看fork fork()函数两个返回值问题 fork()函数的实现在操作系统内部,函数准备return的时候核心代码已经执行完...**这是我们在进程地址空间时候所说的。**这也很好理解 fork常用法:1.一个父进程希望复制自己,使父子进程同时执行不同的代码段。2.一个进程要执行一个不同的程序。...用户级的缓冲区(doge)对于缓冲区在哪的问题后面涉及到在细谈 ---- 四、进程等待 我们知道,进程有一种Z(僵尸)状态,Z状态是一个问题:子进程退出,父进程如果不管不顾,就可能造成‘僵尸进程’的问题.../waitpid等子进程时,直到子进程退出,这是阻塞时等待 非阻塞等待(WNOHANG):检测状态,如果没有就绪父进程检测之后立即返回。...printf也是代码,在exec之后,exec执行完毕之后代码已经全部被覆盖,开始执行新的代码,所以第二个printf就无法执行了。
导语:这是篇读书笔记,每次重读CSAPP都有新的认知,尤其是在进入了后台通道之后才感受到每天和进程打交道的感觉是如此深刻。 0x00 What is Process?...ID Creating and Terminating Process 从程序角度来看,进程总处于以下三种状态: Running——要么处于CPU执行中,要么处于等待被执行且最终会被内核调度。...fork():一次调用,返回两次。 1)在调用进程中(父进程),返回子进程PID; 2)在新创建的子进程中,在子进程中返回0。 并发执行:父子进程是并发运行的独立进程。...子进程与父进程用户级虚拟地址空间相同的拷贝,相同的本地变量值、堆、全局变量、以及代码。如代码中print出来不一样的x。...exit Reap Child Process 进程终止时,保持位已终止状态,直到被父进程回收(reap)。
当我们去掉printf后,进程始终都在运行状态里,所以最终查出来的状态是运行状态(R状态)。 休眠状态本质就是进程在等待“资源”就绪 当程序正在运行时,如果ctrl+c,进程被终止,称为可中断睡眠。...,可以使用指令kill -19 进程的pid来让进程处于停止状态 T/t状态:让进程处于暂停状态。...当进程退出并且父进程(使用wait()系统调用,后面讲)没有读取到子进程退出的返回代码时就会产生僵死(尸)进程 僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。...如果没有父进程读取,僵尸进程会一直存在。 上述代码中,子进程执行完五次后,就处于Z状态并且后面跟了一个,该单词有不存在的意思,只不过还等待父进程来回收它的资源。...父进程也是bash的子进程,父进程结束后,它的父进程bash会将它回收掉,并且过程很快,所以父进程不会处于僵尸状态。
对换的需要 为了缓解内存紧张的情况,即将内存中处于阻塞状态的进程换至辅存上,使进程又处于一种有别于阻塞状态的新状态。...由创建者提供,通常由字母、数字所组成,往往是由用户(进程)在访问该进程时使用。 ②内部标识符。这是为了方便系统使用而设置的。...+要求的服务时间)/要求的服务时间 ,每次选取响应比最高的进程调度 -优点:所以对短进程有利,并且考虑了等待时间 -缺点:计算响应比有一定的系统开销 优先级调度算法 -算法:...将CPU分配给就绪队列中优先级最高的进程 -静态优先级 在进程创建时确立,确定后运行期间保持不变。...系统应将它重新放到就绪队列的末尾,等待下次执行 进程调度的时机和过程 进程调度的时机 -正在执行的进程运行完毕 -正在执行的进程调用阻塞原语将自己阻塞起来进入等待状态 -在采用抢占式优先级调度时
领取专属 10元无门槛券
手把手带您无忧上云