日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

wait/waitpid函数与僵尸进程、fork 2 times

發布時間:2024/9/21 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 wait/waitpid函数与僵尸进程、fork 2 times 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、僵尸進程

當子進程退出的時候,內核會向父進程發送SIGCHLD信號,子進程的退出是個異步事件(子進程可以在父進程運行的任何時刻終止)
子進程退出時,內核將子進程置為僵尸狀態,這個進程稱為僵尸進程,它只保留最小的一些內核數據結構,以便父進程查詢子進程的退出狀態。


A?child?that?terminates,?but?has?not?been?waited?for?becomes?a?"zombie".??The?kernel?maintains?a?
minimal?set?of?information??about?the??zombie??process?(PID,?termination?status,?resource?usage?
information)?in?order?to?allow?the?parent?to?later?perform?a?wait?to?obtain?information?about?the?
child.??As?long?as?a?zombie?is?not?removed?from?the?system?via?a?wait,?it?will?consume?a?slot?in? ? the?kernel??process??table,??and?if?this?table?fills,?it?will?not?be?possible?to?create?further?
processes.??If?a?parent?process?terminates,?then?its?"zombie"?children?(if?any)?are?adopted?by?
init(8),?which?automatically?performs?a?wait?to?remove?the?zombies.

?

父進程查詢子進程的退出狀態可以用wait/waitpid函數。


二、如何避免僵尸進程

當一個子進程結束運行時,它與其父進程之間的關聯還會保持到父進程也正常地結束運行或者父進程調用了wait/waitpid才告終止。
進程表中代表子進程的數據項是不會立刻釋放的,雖然不再活躍了,可子進程還停留在系統里,因為它的退出碼還需要保存起來以備父進程中后續的wait/waitpid調用使用。它將稱為一個“僵進程”。

調用wait或者waitpid函數查詢子進程退出狀態,此方法父進程會被掛起(waitpid可以設置不掛起)。
如果不想讓父進程掛起,可以在父進程中加入一條語句:signal(SIGCHLD,SIG_IGN);表示父進程忽略SIGCHLD信號,該信號是子進程退出的時候向父進程發送的。也可以不忽略SIGCHLD信號,而接收在信號處理函數中調用wait/waitpid。

// 讓子進程退出后自動回收,避免成為僵尸或者需要父進程 wait。
struct sigaction sat_cld = { .sa_handler = SIG_IGN, .sa_flags = SA_NOCLDWAIT };
sigaction(SIGCHLD, &sat_cld, NULL);

而在運維中常用的手段是殺死父進程,這樣子進程會由init 進程接管,由它來清理子進程的狀態。


三、wait函數

頭文件<sys/types.h>和<sys/wait.h>
函數功能:當我們用fork啟動一個進程時,子進程就有了自己的生命,并將獨立地運行。有時,我們需要知道某個子進程是否已經結束了,我們可以通過wait安排父進程在子進程結束之后。
函數原型
pid_t wait(int *status)
函數參數
status:該參數可以獲得你等待子進程的信息
返回值:
成功等待子進程, ?函數返回等待子進程的ID


wait系統調用會使父進程暫停執行,直到它的一個子進程結束為止。
返回的是子進程的PID,它通常是結束的子進程
狀態信息允許父進程判定子進程的退出狀態,即從子進程的main函數返回的值或子進程中exit語句的退出碼。
如果status不是一個空指針,狀態信息將被寫入它指向的位置


通過以下的宏定義可以獲得子進程的退出狀態

WIFEXITED(status) 如果子進程正常結束,返回一個非零值
WEXITSTATUS(status) 如果WIFEXITED非零,返回子進程退出碼
WIFSIGNALED(status) 子進程因為捕獲信號而終止,返回非零值
WTERMSIG(status) 如果WIFSIGNALED非零,返回信號代碼
WIFSTOPPED(status) 如果子進程被暫停,返回一個非零值
WSTOPSIG(status) 如果WIFSTOPPED非零,返回一個信號代碼


四、waitpid函數

函數功能:用來等待某個特定進程的結束

函數原型:
pid_t waitpid(pid_t pid, int *status,int options)
?參數:
status:如果不是空,會把狀態信息寫到它指向的位置
options:允許改變waitpid的行為,最有用的一個選項是WNOHANG,它的作用是防止waitpid把調用者的執行掛起等待(return immediately if no child has exited.)
返回值:如果成功, 返回等待子進程的ID,失敗返回-1


對于waitpid的p i d參數的解釋與其值有關:
pid == -1 等待任一子進程。于是在這一功能方面waitpid與wait等效。
pid > 0 等待其進程I D與p i d相等的子進程。
pid == 0 等待其組I D等于調用進程的組I D的任一子進程。換句話說是與調用者進程同在一個組的進程。
pid < -1 等待其組I D等于p i d的絕對值的任一子進程。


五、wait和waitpid函數的區別

兩個函數都用于等待進程的狀態變化,包括正常退出,被信號異常終止,被信號暫停,被信號喚醒繼續執行等。

在一個子進程終止前, wait 使其調用者阻塞,而waitpid 有一選擇項,可使調用者不阻塞。
waitpid并不只能等待第一個終止的子進程—它有若干個選擇項,可以控制它所等待的特定進程。
實際上wait函數是waitpid函數的一個特例。


RETURN VALUE


? ? ? ?wait(): on success, returns the process ID of the terminated child; on error, -1 is returned.

? ? ? ?waitpid(): on success, returns the process ID of the child whose state has changed; if WNOHANG ?was ?specified ?and ?one ?or ?more
? ? ? ?child(ren) specified by pid exist, but have not yet changed state, then 0 is returned. ?On error, -1 is returned.


示例程序:

?

C++ Code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
? /*************************************************************************
????>?File?Name:?process_.c
????>?Author:?Simba
????>?Mail:?dameng34@163.com
????>?Created?Time:?Sat?23?Feb?2013?02:34:02?PM?CST
?************************************************************************/
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<sys/wait.h>

#define?ERR_EXIT(m)?\
????do?{?\
????????perror(m);?\
????????exit(EXIT_FAILURE);?\
????}?while(0)

int?main(int?argc,?char?*argv[])
{
????pid_t?pid;
????pid?=?fork();
????if?(pid?==?-1)
????????ERR_EXIT("fork?error");

????if?(pid?==?0)
????{
????????sleep(3);
????????printf("this?is?child\n");
????????//??????exit(100);
????????abort();
????}

????printf("this?is?parent\n");
????int?status;
????int?ret;
????ret?=?wait(&status);?//?阻塞等待子進程退出
????//??ret?=?waitpid(-1,?&status,?0);
????//??ret?=?waitpid(pid,?&status,?0);
????/*?waitpid可以等待特定的進程,而不僅僅是第一個退出的子進程
?????*?且可以設置option為WNOHANG,即不阻塞等待?*/
????printf("ret=%d,?pid=%d\n",?ret,?pid);
????if?(WIFEXITED(status))
????????printf("child?exited?normal?exit?status=%d\n",?WEXITSTATUS(status));
????else?if?(WIFSIGNALED(status))
????????printf("child?exited?abnormal?signal?number=%d\n",?WTERMSIG(status));
????else?if?(WIFSTOPPED(status))
????????printf("child?stopped?signal?number=%d\n",?WSTOPSIG(status));

????return?0;
}

?

輸出為:

simba@ubuntu:~/Documents/code/linux_programming/APUE/process$ ./wait?
this is parent
this is child
ret=7156, pid=7156
child exited abnormal signal number=6

說明子進程被信號異常終止,因為我們調用了abort(), 即產生SIGABRT信號將子進程終止,可以查到此信號序號為6。如果我們不使用abort 而是exit(100), 則應該輸出?child?exited?normal?exit?status=100 ?,即正常退出。


也就是所謂兩次 fork 調用,主進程并不直接創建目標子進程,而是通過創建一個 Son,然后再由Son 創建實際的目標子進程 Grandson。Son 在創建?


Grandson 后立即返回,并由主進程 waitpid回收掉。而真正的目標 Grandson 則因為 "生父" Son 死掉而被 init 收養,然后直接被人道毀滅。


?

C++ Code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
? void?create_child()
{
????pid_t?son?=?fork();
????if?(son?==?0)
????{
????????pid_t?grandson?=?fork();
????????if?(grandson?==?0)
????????{
????????????printf("child:?%d,?parent:?%d\n",?getpid(),?getppid());
????????????exit(EXIT_SUCCESS);
????????}
????????exit(EXIT_SUCCESS);
????}
????else?if?(son?>?0)
????{
????????waitpid(son,?NULL,?0);
????}
????else
????{
????????perror("fork");
????}
}

int?main(int?argc,?char?*argv[])
{
????for?(int?i?=?0;?i?<?10;?i++)
????{
????????create_child();
????}
????while(true)?pause();
????return?EXIT_SUCCESS;
}

?

參考:《APUE》

轉載于:https://www.cnblogs.com/alantu2018/p/8477199.html

總結

以上是生活随笔為你收集整理的wait/waitpid函数与僵尸进程、fork 2 times的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 暴力调教一区二区三区 | 日韩视频在线一区 | av在线不卡网站 | 国产精品第一国产精品 | 亚洲欧洲日韩综合 | 国产在线美女 | 日韩精品在线观看AV | 久操视频精品 | 亚洲精品国产美女 | 欧美日韩激情在线一区二区三区 | 麻豆视频一区二区三区 | 日本韩国毛片 | 国产精品又黄又爽又色无遮挡 | 色婷婷视频 | 91成人品 | 久久手机免费视频 | 亚洲天堂福利视频 | 91福利一区 | 日韩无码专区 | 夜夜天天拍拍 | 国产精品久久久久久69 | 四虎永久在线精品免费一区二区 | av资源库| 97自拍偷拍视频 | 中国色老太hd | 免费成人深夜夜视频 | 欧美麻豆 | 色综合久久88色综合天天 | 精品少妇一区二区三区在线观看 | 欧洲中文字幕日韩精品成人 | 国产无遮挡又黄又爽在线观看 | 夜夜爽妓女8888视频免费观看 | av大片免费 | 成人午夜影院在线观看 | xxxx在线播放| 在线aaa | 艳情五月| 天天想你免费观看完整版高清电影 | jzzjzz日本丰满成熟少妇 | 国产真人做爰毛片视频直播 | 中文字幕在线日亚洲9 | 伊人久久精品视频 | 午夜电影一区二区 | 国产欧美激情视频 | 亚洲女优在线 | 婷婷亚洲一区 | 岳狂躁岳丰满少妇大叫 | 香港日本韩国三级网站 | h无码动漫在线观看 | 欧美 亚洲 另类 激情 另类 | 中文字幕无码日韩专区免费 | 国产美女作爱视频 | 亚洲av区无码字幕中文色 | av网站入口| 欧美区一区二区三 | 中日韩午夜理伦电影免费 | 成人午夜影视在线观看 | 国产激情视频在线 | 天天色天天综合 | 亚洲国产精品成人无码区 | 日本国产精品视频 | 国产欧美一区二区精品性色99 | 豆豆色成人网 | 久久久无码18禁高潮喷水 | 黑人极品videos精品欧美裸 | 日韩理论在线观看 | 福利视频网站 | 青青草视频免费播放 | 久热伊人 | 国产二三区 | 真人真事免费毛片 | 国产成人精品一区二区在线小狼 | 天天曰天天干 | 男人和女人日批视频 | 免费人成网站 | 双性受孕h堵精大肚生子 | 日韩欧美理论片 | 久久99久久99精品中文字幕 | www.天天射 | 污视频网站免费在线观看 | 91精品亚洲 | 色呦呦在线视频 | 亚洲天堂视频网 | 国产一区二区三区在线播放无 | 三级在线网站 | 4444亚洲人成无码网在线观看 | 欧美一区二区三区爽爽爽 | 久久一区二 | 美女又爽又黄视频 | 综合色在线视频 | 成人av在线网址 | 天堂中文8| 日本国产一区二区三区 | 国产精品福利一区二区三区 | 伊人色爱| 夜色88v精品国产亚洲 | 一级黄色裸体片 | 国产午夜大地久久 | 咪咪色在线视频 |