6进程原语:wait()和waitpid()函数
1 wait/waitpid
僵尸進程: 子進程退出,父進程沒有回收子進程資源(PCB),則子進程變成僵尸進程
孤兒進程: 父進程先于子進程結束,則子進程成為孤兒進程,子進程的父進程成為1號
進程init進程,稱為init進程領養孤兒進程
2依賴的頭文件
#include <sys/types.h>
#include <sys/wait.h>
3函數聲明
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, intoptions);
?
The value of pid can be:
??????< -1?? meaning wait for anychild process whose? process? group?ID? is
????????????? equal to the absolute value ofpid.
?
??????-1???? meaning wait for any childprocess.
?
??????0????? meaning? wait?for? any? child process whose process group ID is
????????????? equal to that of the callingprocess.
?
??????> 0??? meaning wait for thechild whose process? ID? is?equal? to? the
????????????? value of pid.
< -1 回收指定進程組內的任意子進程
-1 回收任意子進程
0 回收和當前調用waitpid一個組的所有子進程
> 0 回收指定ID的子進程
3.說明:
一個進程在終止時會關閉所有文件描述符,釋放在用戶空間分配的內存,但它的PCB還
保留著,內核在其中保存了一些信息:如果是正常終止則保存著退出狀態,如果是異常終止
則保存著導致該進程終止的信號是哪個。這個進程的父進程可以調用wait或waitpid獲取這
些信息,然后徹底清除掉這個進程。我們知道一個進程的退出狀態可以在Shell中用特殊變
量$?查看,因為Shell是它的父進程,當它終止時Shell調用wait或waitpid得到它的退出狀
態同時徹底清除掉這個進程。
如果一個進程已經終止,但是它的父進程尚未調用wait或waitpid對它進行清理,這時
的進程狀態稱為僵尸(Zombie)進程。任何進程在剛終止時都是僵尸進程,正常情況下,僵
尸進程都立刻被父進程清理了,為了觀察到僵尸進程,我們自己寫一個不正常的程序,父進
程fork出子進程,子進程終止,而父進程既不終止也不調用wait清理子進程:
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
pid_t pid=fork();
if(pid<0) {
perror("fork");
exit(1);
}
if(pid>0) { /* parent */
while(1);
}
/* child */
return 0;
}
若調用成功則返回清理掉的子進程id,若調用出錯則返回-1。父進程調用wait或
waitpid時可能會:
* 阻塞(如果它的所有子進程都還在運行)。
* 帶子進程的終止信息立即返回(如果一個子進程已終止,正等待父進程讀取其終止信
息)。
* 出錯立即返回(如果它沒有任何子進程)。
這兩個函數的區別是:
* 如果父進程的所有子進程都還在運行,調用wait將使父進程阻塞,而調用waitpid時如果在options參數中指定WNOHANG可以使父進程不阻塞而立即返回0。
* wait等待第一個終止的子進程,而waitpid可以通過pid參數指定等待哪一個子進程。
可見,調用wait和waitpid不僅可以獲得子進程的終止信息,還可以使父進程阻塞等待子進
程終止,起到進程間同步的作用。如果參數status不是空指針,則子進程的終止信息通過
這個參數傳出,如果只是為了同步而不關心子進程的終止信息,可以將status參數指定為
NULL。
例waitpid
The?value? of? options?is an OR of zero or more of the following con‐
??????stants:
??????WNOHANG???? return immediately ifno child has exited.
??????WUNTRACED?? also return if a childhas? stopped? (but?not? traced? via
?????????????????? ptrace(2)).?? Status for traced children which havestopped
?????????????????? is provided even if thisoption is not specified.
??????WCONTINUED (since Linux 2.6.10)
?????????????????? also return if a stoppedchild has been resumed by delivery
?????????????????? of SIGCONT.
??????(For Linux-only options, see below.)
If status is not NULL, wait() and waitpid()store status information in
??????the int to which it points.? Thisinteger can? be? inspected?with? the
??????following? macros? (which take the integer itself as anargument, not a
??????pointer to it, as is done in wait() and waitpid()!):
?
??????WIFEXITED(status)
????????????? returns true if the childterminated normally, that is, by call‐
????????????? ing exit(3) or _exit(2), or byreturning from main().
?
??????WEXITSTATUS(status)
????????????? returns? the?exit? status? of? thechild.? This consists of the
????????????? least significant 8 bits of thestatus argument that? the? child
????????????? specified? in?a? call to exit(3) or _exit(2) oras the argument
????????????? for a return statement inmain().? This macro should be employed
????????????? only if WIFEXITED returned true.
?
??????WIFSIGNALED(status)
????????????? returns true if the child processwas terminated by a signal.
?
??????WTERMSIG(status)
????????????? returns? the?number of the signal that caused the child process
????????????? to terminate.? This macro should be employed only ifWIFSIGNALED
????????????? returned true.
WCOREDUMP(status)
???? ?????????returns? true?if? the? child?produced a core dump.? This macro
????????????? should be employed only? if?WIFSIGNALED? returned? true.??This
????????????? macro? is? notspecified in POSIX.1-2001 and is not available on
????????????? some UNIX implementations (e.g.,AIX,? SunOS).?? Only?use? this
????????????? enclosed in #ifdef WCOREDUMP ...#endif.
?
??????WIFSTOPPED(status)
????????????? returns? true?if the child process was stopped by delivery of a
????????????? signal; this is possible only ifthe call was? done? using?WUN‐
????????????? TRACED or when the child is beingtraced (see ptrace(2)).
?
??????WSTOPSIG(status)
????????????? returns the number of the signalwhich caused the child to stop.
????????????? This macro should be employedonly if WIFSTOPPED returned true.
?
??????WIFCONTINUED(status)
????????????? (since Linux 2.6.10) returns? true?if? the? child?process? was
????????????? resumed by delivery of SIGCONT.
?
#include <sys/wait.h>
??????#include <stdlib.h>
??????#include <unistd.h>
??????#include <stdio.h>
?
??????int
??????main(int argc, char *argv[])
??????{
??????????pid_t cpid, w;
??????????int status;
?
??????????cpid = fork();
??????????if (cpid == -1) {
?????????????? perror("fork");
?????????????? exit(EXIT_FAILURE);
??????????}
?
??????????if (cpid == 0) {??????????? /*Code executed by child */
?????????????? printf("Child PID is%ld\n", (long) getpid());
?????????????? if (argc == 1)
?????????????????? pause();??????????????????? /* Wait for signals */
?????????????? _exit(atoi(argv[1]));
} else {??????????????????? /*Code executed by parent */
?????????????? do {
?????????????????? w = waitpid(cpid,&status, WUNTRACED | WCONTINUED);
?????????????????? if (w == -1) {
?????????????????????? perror("waitpid");
?????????????????????? exit(EXIT_FAILURE);
?????????????????? }
?
?????????????????? if (WIFEXITED(status)) {
?????????????????????? printf("exited,status=%d\n", WEXITSTATUS(status));
?????????????????? } else if(WIFSIGNALED(status)) {
???? ??????????????????printf("killed by signal%d\n", WTERMSIG(status));
?????????????????? } else if(WIFSTOPPED(status)) {
?????????????????????? printf("stopped bysignal %d\n", WSTOPSIG(status));
?????????????????? } else if(WIFCONTINUED(status)) {
??????????????????????printf("continued\n");
?????????????????? }
?????????????? } while (!WIFEXITED(status)&& !WIFSIGNALED(status));
?????????????? exit(EXIT_SUCCESS);
??????????}
??????}
總結
以上是生活随笔為你收集整理的6进程原语:wait()和waitpid()函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 3进程状态getrlimit()函数和s
- 下一篇: 光大信用卡白金卡年费