[英]What happens when fork() in a condition?
誰能給我這個代碼的輸出(有解釋)? 謝謝...
#include <stdio.h>
#include <unistd.h>
int main()
{
if (fork() && (!fork())) {
if (fork() || fork()) {
fork();
}
}
printf("Friend\n");
return 0;
}
在進入代碼之前最好先了解什么是 fork() 系統調用
fork() 系統調用由“父”創建一個新進程,新創建的進程稱為“子”進程
當fork成功時,子進程返回0,父進程返回正整數
這就是這里的線索
因此,從該程序計數器開始,所有兩個進程都同時工作......
在這里 fork() 處於 if 條件,並且在猜測輸出時也有點棘手
首先 fork() 創建新的 C1 -> 0
第二個 fork() 創建新的 C2 -> !0 -> 1
所以第一個條件由 C2(其父正整數和 c2 為 0)統計,但未由父或子 C1 統計,因此其他分叉將不起作用
然后 C2 進入另一個 if 條件並制作另外兩個叉子
C2
/ \
C2 C3
/ \ / \
C2 c4 c3 c5
然后所有創建的進程(包括父進程)打印“朋友”輸出 7 次
快速回答是父母會做某事,而孩子會做其他事情。 但是繼續閱讀……
好吧,我只是稍微修改了您的代碼,您將從程序的輸出中獲得所有進程層次結構,以及您問題的答案:
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
static pid_t my_fork() /* tracing is your friend! :) */
{
pid_t chld = fork();
if (chld > 0) {
/* only the parent shows this */
printf("[pid=%d, child=%d] forked!\n",
getpid(), chld);
}
return chld;
}
int main()
{
/* print our pid, so we know the root of the hierarchy */
printf("[pid=%d] Hello, world\n", getpid());
/* do the embarrasing work */
if (my_fork() && (!my_fork())) {
if (my_fork() || my_fork()) {
my_fork();
}
}
pid_t pid;
int status;
/* We do wait(2)'s while there are children to be waited for.
* it's a good thing to wait for children before ending. */
while((pid = wait(&status)) >= 0) {
printf("[pid=%d, child=%d]: child ended with status=%d\n",
getpid(), pid, status);
}
/* we print the message when no more children are alive */
printf("[pid=%d]: Hello friend!\n", getpid());
return 0;
}
這會產生
$ pru
[pid=72699] Hello, world
[pid=72699, child=72700] forked!
[pid=72699, child=72701] forked!
[pid=72700]: Hello friend!
[pid=72701, child=72702] forked!
[pid=72703]: Hello friend!
[pid=72699, child=72700]: child ended with status=0
[pid=72702, child=72703] forked!
[pid=72702, child=72705] forked!
[pid=72702, child=72703]: child ended with status=0
[pid=72705]: Hello friend!
[pid=72704]: Hello friend!
[pid=72701, child=72704] forked!
[pid=72701, child=72704]: child ended with status=0
[pid=72702, child=72705]: child ended with status=0
[pid=72702]: Hello friend!
[pid=72701, child=72702]: child ended with status=0
[pid=72701]: Hello friend!
[pid=72699, child=72701]: child ended with status=0
[pid=72699]: Hello friend!
這是層次結構:
[pid=72699] (says Hello, world, just starting)
+-[pid=72700] (created in first fork() call of pid=72699)
`-[pid=72701] (created in second fork() call of pid=72699)
+-[pid=72702] (created in third fork() call of pid=72701)
| +-[pid=72703] (created in fourth fork() call of pid=72702)
| `-[pid=72705] (created in fifth fork() call of pid=72702)
`-[pid=7204] (created in fourth fork() call of pid=72701)
(當然,如果進程用完了,層次會不一樣, fork(2)
因為系統資源不足而失敗)
最后,您可能會擔心為什么消息
[pid=72703]: Hello friend!
出現在消息之前
[pid=72702, child=72703] forked!
但這就是多任務處理的奇妙世界。 在fork(2)
返回后打印消息,因此兩條消息由不同的進程打印,因此,它們可以按任何順序進行調度,因此子進程在父進程有機會打印誰是他的孩子。 這是完全正常的。
您必須注意fork()
在出錯時返回-1
,它在布爾測試中評估為true
,就像父級的結果一樣。 因此,如果您自由地將fork(2)
的返回代碼用於布爾表達式,則父級將收到true
或fork()
失敗時發生的任何錯誤(好吧,它們很少,但它們在加載的系統上是可能的)。 只需保存fork()
的結果代碼並首先檢查錯誤,然后您就可以隨意使用任何您想要的布爾表達式。
上面的源代碼可以在這里下載
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.