#include pid_t fork(void); //返回值:子进程中返回0,父进程返回子进程id,出错返回-1 进程调用fork,当控制转移到内核中的fork代码后,内核做:...但每个进程都将可以 开始它们自己的旅程。 fork 函数返回值 子进程返回0, 父进程返回的是子进程的pid。 为什么父进程返回的是子进程的pid?...子进程运行五秒后退出,此时由于父进程还在休眠无法回收,所以子进程就变成Z状态,再过五秒后,子进程就被父进程回收了。...Pid>0.等待其进程ID与pid相等的子进程。 status: WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。...实际上我们不使用位操作符处理status,而是使用两个宏,WIFEXITED和WEXITSTATUS。 WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。
例如子进程从fork返回后,调用exec函数 1.2 .fork()函数创建失败的原因 系统中有太多的进程。 实际用户的进程数超过了限制 。...、退出信号 return 0; } 3.4.2利用宏来获取子进程退出状态 WIFEXITED(status):检查子进程是否正常退出。...如果子进程通过调用exit函数或main函数return返回而退出,则WIFEXITED返回非0值(真) ->正常退出;(进程是正常退出的,进程信号返回的是0,当进程信号为0时,WIFEXITED的返回值是非...0) 如果子进程是由于接收到信号而退出,则WIFEXITED返回0(假) -> 异常退出。...(进程是异常退出的,进程信号返回的是非,当进程信号为非时,WIFEXITED的返回值是0) WEXITSTATUS(status):只有当WIFEXITED为真时(即进程是正常退出的,进程信号为0),接着才会使用
L010Linux和androidNDK之linux避免僵尸进程,子进程退出的处理 如果你在程序中fork出一个子进程,没有好好处理子进程退出后的相关事宜,那么就有可能召唤出传说中进程界的僵尸---僵尸进程...,并不能将其完全销毁) 僵尸进程是怎么样产生 在Linux进程的状态中,僵尸进程是非常特殊的一种,它已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集...(1)当子进程结束之后,但父进程未结束之前,子进程将成为僵尸进程,父进程结束后僵尸被init进程回收。...*Note Signal Handling:: 子进程的结束状态返回后存于status,如下有几个宏可判别结束情况 WIFEXITED(status)如果子进程正常结束则为非0值。...WEXITSTATUS(status)取得子进程exit()返回的结束代码,一般会先用WIFEXITED 来判断是否正常结束才能使用此宏。
2.2 fork函数返回值 子进程返回0 父进程返回的是子进程的pid 那为什么父进程返回子进程PID ,给子进程返回0呢???...例如子进程从fork返回后,调用exec函数。 一般使用if else 分开书写,也可以通过系统调用打开新的进程。...父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息 也就是说,任何进程在退出时都要被父进程进行等待,不然子进程处于僵尸进程就会造成内存泄漏!!!...(查看进程是否是正常退出) WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。...(查看进程是否是正常退出) WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码) 对于第三个参数,就可以让父进程在等待的刚才中区做其他事情。
> fork成功后对子进程返回0,对父进程返回子进程id,fork出错返回-1 内核视角看待fork: 进程调用fork,内核分配新的内存块和内核数据结构给子进程 将父进程部分数据结构内容拷贝至子进程...: 只有是在main函数的的return才算是终止进程,其他函数return只是结束函数,因为系统调用的是main函数,main函数返回才是进程的返回 调用main函数运行结束后,main函数的...,以此获取子进程退出的信息 使用对应的宏可以查看我们需要的退出信息:WIFEXITED(status): 若为正常终止子进程返回的状态,则为真(查看进程是否是正常退出);WEXITSTATUS(status...): 若WIFEXITED非零,提取子进程退出码(查看进程的退出码) 参数options: 设置为0:表示默认的阻塞式等待子进程退出,即子进程没退出就不返回,一直等待到子进程退出回收子进程...如果传递变量地址,操作系统会根据该参数将子进程的退出信息反馈给父进程 使用对应的宏可以方便查看我们需要的退出信息:WIFEXITED(status): 若为正常终止子进程返回的状态,则为真(查看进程是否是正常退出
ID在3秒后变成了1,这说明父进程结束后,它变成了孤儿进程,并被init进程收养,使用kill命令基于可以杀死孤儿进程。...WIFEXITED(status)判断子进程是否正常退出; WIFEXITED(status)为真表示正常退出,使用WEXITSTATUS(status)获取退出状态; WIFEXITED(status...,立即返回,不会挂起等待(wait函数如果子进程没有退出会阻塞等待)。...如果设置了WNOHANG选项,并且没有子进程退出则返回0,如果有子进程退出则返回退出子进程的pid。 On error, -1 is returned....当waitpid()返回父进程中后,子进程才结束,但是waitpid()已经执行完了,所以并没有回收子进程,子进程因此变成僵尸进程。
,回收系统资源(一定要考虑的) 获取子进程的退出信息,知道子进程是因为什么原因退出的(可选的功能) 系统调用 wait() wait() 函数使调用的进程(通常是父进程)暂停执行,直到一个子进程终止或发生一个信号...如果不存在该子进程,则立即出错返回 所以说父进程通过等待,解决子进程退出的僵尸问题,回收系统资源 如果子进程没有退出,父进程其实一直在进行阻塞等待!...返回非零值表示子进程正常退出,可以通过 WEXITSTATUS(status) 获取退出状态。 WEXITSTATUS(status): 在 WIFEXITED(status) 为真时使用。...fork() 在父进程中返回子进程的 PID,在子进程中返回 0。 由于操作系统的调度策略,父进程和子进程之后的执行顺序是不确定的。...退出处理 (exit()): 在子进程中,如果 execl() 调用失败,紧接着调用 exit(1) 来结束子进程,并返回状态码 1。
,可以通过以下宏来检查子进程的退出原因: WIFEXITED(status): 子进程是否正常退出。...wait() 在没有子进程时返回 -1 并设置 errno 为 ECHILD。...它们主要用于进程管理和控制,是系统编程中非常重要的工具 1:是什么 2:为什么也就是必要性 之前说过,子进程退出,父进程如果不管不顾,就可能造成‘僵尸进程’的问题,进而造成内存泄漏。...父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息 wait回收僵尸进程(父进程等待是必须的)(wait成功返回的是回收子进程的PI,失败返回-1) 运行后子进程的状态是S+,然后5秒后就会变成...for循环后,经过fork创建了一个子进程进入了RunChild,然后执行完RunChild后,exit(0),就退出子进程了,然后父进程再次进入循环,再次创建一个子进。。。。。。
#include pid_t fork(void); 返回值:自进程中返回0,父进程返回子进程id,出错返回-1 进程调用fork,当控制转移到内核中的fork代码后,内核做: 分配新的内存块和内核数据结构给子进程...例如子进程从fork返回后,调用exec函数。...⭐进程等待 进程等待的必要性 在Linux进程提到过,子进程退出,父进程如果不管不顾,不读取子进程的退出信息,就可能造成“僵尸进程”的问题,进而造成内存泄漏。...Pid>0.等待其进程ID与pid相等的子进程。 status: WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。...(查看进程是否是正常退出) WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。
在我们的代码进程中,在任意地方调用exit都表示进程退出。...采用非阻塞的方法等待,子进程退出成功返回子进程的pid,子进程还在继续自己的工作返回0,子进程出错返回小于0的数。...阻塞等待时父进程会阻塞在waitpid这里一直等待子进程返回,非阻塞等待采用轮询的方法查看子进程的退出信息,在轮询的间隙父进程可以继续做别的工作。...因为子进程的退出码为1,status的第24个比特位被设置为1,没有收到退出信号,所以status后8个比特位都为0,所以status等于2的8次方等于256。 ...WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)。 WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。
进程等待必要性 在了解完进程等待的概念后,新的问题出现了,我们为什么要进行进程等待,进程等待的必要性是什么?...进程等待的方法 3.1 wait方法 我们可以通过系统调用来等待进程:wait函数 wait等待任意一个子进程的退出,如果等待成功他将返回子进程的pid,失败则返回-1 我们就用一段代码来看看wait:...通过这个视频我们又能发现两个进程一起运行,但是在子进程没有退出之前,父进程一直在wait上等待,并且并没有出现子进程僵尸状态而是直接回收了。...,因此系统给我们做了一个简单的封装 status: WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。...(查看进程是否是正常退出) WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。
父进程为什么要等待子进程 在前面上篇我们已经讲过僵尸状态的问题,子进程在执行结束后,如果父进程不及时进行接受处理,子进程就会进入僵尸状态,进入僵尸状态后,从而造成内存泄漏,而且kill -9信号也不能进行处理...父进程等待子进程的常用函数 Linux 提供了多个函数用于父进程等待子进程的结束: 函数名 描述 wait() 阻塞父进程,直到任一子进程退出,返回退出的子进程 PID。...= wait(&status); // 等待任意子进程结束 if (WIFEXITED(status)) { // 检查子进程是否正常退出 printf("...使用宏 WIFEXITED 和 WEXITSTATUS 分别检查子进程是否正常退出及其退出码。...僵尸进程与避免方法 文章开头我们就已经讲过僵尸进程了,通过上面对进程等待的学习,再来看一下僵尸进程的概念,看看能不能加深理解 僵尸进程(Zombie Process) 是指子进程退出后,其退出信息尚未被父进程读取的状态
退出码的作用就是告诉父进程,子进程的退出状态-是正常结束了还是出现错误终止了; 2.为什么要用退出码判断进程是否出错,直接printf不好吗?...,然后继续执行后序的代码,这个时候就需要等待子进程完成任务后,获取子进程的退出码看看他完成的怎么样了; 2.避免僵尸进程:子进程先父进程结束会出现僵尸状态,造成进程卡死,无法回收,所以我们只需要阻塞父进程让他等待子进程完成...调用函数,自己帮我们填充这个变量的; wait函数等待成功后,status就会获得该子进程的退出码; 为什么不使用全局变量来获取子进程的退出状态呢?...WIFEXITED(status) : 若为正常终止子进程返回的状态,则为真。...(查看进程是否是正常退出) 其实等价于status&0x7F (2) WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。
fork()为什么会出现两个返回值❓ 根据fork()函数在内核中的操作就包含了子进程的数据结构的创建,所以在fork()返回之前,子进程就已经被创建出来了。...()函数外面看到的现象就是一个函数出现了两个返回值 .为什么子进程要返回0,而父进程要返回子进程的PID❓ 一个父进程可以创建很多的子进程,而每一个子进程都只能有一个父进程 而父进程创建子进程是为了让子进程完成任务的...在status的后16个比特位上,高8位表示进程退出的状态,即进程退出码。而后7位为进程终止的信号。第8个比特位是一个标志 注意:当进程正常退出的时候,不用查看退出信号。...等待其进程ID与pid相等的子进程。 status: WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。...(查看进程是否是正常退出) WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。
进程调用fork,当控制转移到内核中的fork代码后,内核做: 分配新的内存块和内核数据结构给子进程 将父进程部分数据结构内容拷贝给子进程 添加子进程到系统进程列表当中 fork返回,开始调度器调度 写时拷贝...2、进程终止 main函数的返回值->返回给父进程或系统。...除了上面的位操作获取退出码,还可以使用系统提供的相关宏: WIFEXITED(status): 若为正常终止子进程返回的状态,则为真(查看进程是否是正常退出) WEXITSTATUS(status):...若WIFEXITED非零,提取子进程退出码(查看进程的退出码) 阻塞和非阻塞 非阻塞等待即让父进程在等待子进程的过程中去做一些自己的事。...替换原理: 用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数来执行另一个程序,当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换
wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程...); 如果成功,wait会返回被收集的子进程的进程ID,如果调用进程没有子进程,调用就会失败,此时wait返回-1,同时errno被置为ECHILD。...) 这个宏用来指出子进程是否为正常退出的,如果是,它会返回一个非零值。...2,WEXITSTATUS(status) 当WIFEXITED返回非零值时,我们可以用这个宏来提取子进程的返回值,如果子进程调用exit(5)退出,WEXITSTATUS(status)就会返回5;如果子进程调用...请注意,如果进程不是正常退出的,也就是说,WIFEXITED返回0,这个值就毫无意义。 当然,处理进程退出状态的宏并不止这两个,但它们当中的绝大部分在平时的编程中很少用到。
如果子进程无法创建,或者其状态不能被检索,则返回值为-1; 如果在子进程中不能执行一个shell,或shell未正常的结束,返回值被写入到status的低8~15比特位中;一般为127值 如果所有系统调用都成功...(status) 用来指出子进程是否为正常退出的,如果是,它会返回一个非零值 WEXITSTATUS(status) 用来获取返回值status的低8~15数据 有了这两个宏代码就简介很多,...总结一下,system的返回值需要通过以下三个步骤确定 首先判断子进程是否成功, status !...= -1; 判断子进程是否正常退出, WIFEXITED(status)是否非零; 子进程的返回值, WEXITSTATUS(status) == 0 ; #include #include...命令是否正确执行 Linux system函数返回值 父进程等待子进程终止 wait, WIFEXITED, WEXITSTATUS
一、进程创建 1.1 fork函数初识 #include pid_t fork(void); 返回值:子进程中返回0,父进程返回子进程id,出错返回-1 调用fork函数后,内核做了下面的工作...2、一个进程要执行一个不同的程序。例如子进程从fork返回后,调用exec函数。 ...2.2.2 退出码概念 父进程可以通过拿到子进程的退出码,不同的退出码分别代表的是不同的原因!! 问题1:为什么需要有退出码呢??...(查看进程是否是正常退出) WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。...WIFEXITED(status) : 若为正常终止子进程返回的状态,则为真。
fork返回值返回两次,对于父子进程返回的值不相同,如果需要,我们可以通过if,else来分流,让父子进程在拥有相同代码的基础上实现不同的任务。子进程fork返回0,父进程返回值是子进程的PID。...所以这样的进程拥有独立性的特点。 也是一个进程崩溃不影响另一个的原因。 所以为什么父进程返回的是子进程的PID,子进程的返回时0?...3、进程等待 3、1、进程等待的必要性 任何子进程,在退出的情况下,一般都必须要被父进程等待。如果在退出的时候父进程不管不顾,子进程就会一直保持状态Z,可能还会造成内存泄漏的问题。...Pid>0,等待其进程ID与pid相等的子进程。 status: WIFEXITED(status):若正常终止子进程返回状态,则为真。...(用来查看进程是否正常退出) WEXITSTATUS(status):若WIFEXITED非零则提取子进程退出码。
状态即僵尸状态,最后通过调用 wait 等待后返回子进程信息,子进程结束,只剩父进程运行。...: 如果正常返回时返回收集到的子进程的进程 ID 如果调用中出错则返回 -1,这时 errno 会被设置成相应的值以指示错误所在 如果将 options 设置成 WNOHANG,在调用 waitpid...与之对应的是实参传递给形参是输入型参数; WIFEXITED(status): 查看进程是否正常退出,若为正常终止子进程返回的状态则为真,否则为假 WEXITSTATUS (status): 查看进程退出状态码...,若 WIFEXITED 非零,提取子进程退出状态码 WTERMSIG(status):返回导致子进程终止的信号的编号(也可配合WIFEXITED使用,下面会讲),需要 WIFSIGNALED(status...2、子进程退出后变成僵尸状态,task_struct 中的代码和数据会被释放掉,并把自己的退出信号、退出码写入到自己的 task_struct 中; 3、wait/waitpid 是系统调用,操作系统有资格也有能力去读取子进程的
领取专属 10元无门槛券
手把手带您无忧上云