Wait() 是属于进程的函数。
1.wait()
头文件:

#include<sys/types.h>
#include<wait.h>

函数原型: int wait(int * status)

    当一个进程正常或异常终止时,pcb(内核中的进程控制块)就向其父进程发送SIGCHLD信号。因为子进程终止是个异步事件,这种信号也是内核向父进程发的异步通知。父进程可以忽略该信号,或者提供一个该信号发生时即被调用执行的函数(信号处理程序)。

函数功能:
父进程一旦调用wait函数就立即阻塞自己,由wait分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成zombie的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回,如果没有找到,就一直阻塞,直至找到一个结束的子进程或接收到了一个指定的信号为止。

当父进程忘记调用wait()等待已终止的子进程,子进程就会进入一种没有父进程的状态,此时子进程就是zombie(僵尸)进程。

ps: Wait()与fork()配套出现,如果在fork()之前调用wait(), wait返回-1,正常情况下,应返回子进程pid。
参数status用来保存被收集进程退出时的状态,它是一个指向int类型的指针,如果我们对这个子进程如何死掉的不在意,只想这把这个被僵尸进程消灭掉,就把这个参数置为NULL,
Pid=wait(NULL);
如果成功返回子进程pid,如果没有子进程,失败,则返回-1,同时,error被置为Echild。

如果status的值不是NULL,wait把子进程的退出状态取出并存入其中,这是一个整数值(int)
它指出了子进程是正常退出还是非正常结束,以及正常结束的返回值,或被那个信号结束等信息。由于这些信息被存放在一个整数的不同二进制位中,所以用常规的方法很麻烦。那么,我们就有一个专门的宏macro来完成。
1. WIFEXITED(status)
这个宏用来指出子进程是否正常退出,如果是就返回一个非零值。
注意:这个宏中的参数status不是wait中的那个status,wait中的那个status是指向int型的指针,它指向一个整数值,而那个值就是这个宏中的status。
2. WEXITSTATUS(status)
当WIFEXITED返回非零值时, 即子进程正常退出时,就可以用这个宏提取子进程返回值,如果子进程调用exit(5)退出,返回5(即子进程的退出代码).如果子进程调用exit(0)退出,此时就没有意义了。

2.waitpid()
waitpid()的作用和wait()一样,但它并不一定要等待第一个终止的子进程,它还有若干选项,如可提供一个非阻塞版本的wait()功能等。实际上wait()函数只是waitpid()函数的一个特例,在Linux内部实现wait()函数时直接调用的就是waitpid()函数。

3.下面说说子进程和父进程
1) 父进程先于子进程结束
子进程成了孤儿进程,当父进程退出时,系统会让pid为1的进程接管子进程。
Ps:pid为1的进程是init或者systemd
2) 子进程先于父进程结束
子进程成了僵尸(zombie)进程,并且子进程会一直保持这样的状态直至重启,此时内核只会保留进程的一些必要信息以备父进程所需,此时子进程始终占有资源,同时也减少了系统可以创建的最大进程数。
3) 子进程先于父进程结束,但是父进程调用了wait函数
此时,父进程会等待子进程结束