所以我想弄清楚這段代碼在做什么:
int k = 5;
if(fork() == fork()) k; else --k;
printf("%d\n", k);
困擾我的是我收到不同的輸出:
4
4
4
6
4
4
4
4
4
6
4
4
4
6
4
6
4
4
我添加了一個 PID 檢測器,所以我可以看到所有行程的 id:
int main ()
{
int k = 5;
if(fork() == fork()) k; else --k;
printf("%d\n", k);
int pid;
pid = fork();
if(pid == 0)
{
printf("\n Process id : %d",getpid());
printf("\n Parrent process id : %d\n" ,getppid());
}
return 0;
}
但有時我會得到輸出:
Process id : 9472
Parrent process id : 1413
Process id : 9474
Parrent process id : 1413
Process id : 9471
Parrent process id : 1413
Process id : 9473
Parrent process id : 1413
或者:
Process id : 9557
Parrent process id : 1413
Process id : 9556
Parrent process id : 1413
Process id : 9558
Parrent process id : 9554
Process id : 9559
Parrent process id : 9553
請讓我明白這里發生了什么。
uj5u.com熱心網友回復:
我為孩子們擴展了您的原始代碼,wait以便您確保獲得所有輸出并添加更多輸出。
你有兩個forks 所以總共會有四個行程。
只有在其中一個程序中才會fork() == fork()出現true。這是當這兩個fork()s 中的第一個被呼叫回傳到子行程時,下一個fork()被呼叫并且也回傳到子行程。
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
const char *foo(pid_t a, pid_t b) {
if (a == b) return "child,child";
if (a && b) return "parent,parent";
if (a) return "parent,child";
return "child,parent";
}
int main() {
int k = 5;
pid_t p1, p2;
if ((p1 = fork()) == (p2 = fork())) {
k;
} else {
--k;
}
printf("%d %s\tppid=%d pid=%d\n", k, foo(p1, p2), getppid(), getpid());
int wstatus;
if (p1) wait(&wstatus);
if (p2) wait(&wstatus);
}
示例輸出。請注意,由于所有行程同時運行,因此順序可能會發生變化。
6 child,child ppid=2 pid=4
4 parent,child ppid=1 pid=3
4 child,parent ppid=1 pid=2
4 parent,parent ppid=0 pid=1
在這里,第一個行程 ,1創建了2并且在我們得到了創建3的情況下。2fork() == fork()
1
/ \
2 3
/
4
uj5u.com熱心網友回復:
困擾我的是我收到不同的輸出:
代碼無條件呈現fork()兩次。第一個fork成功后,有兩個程序,原來有一個。 兩者都執行第二個fork,因此,如果所有fork呼叫都成功,最終會有四個行程。
成功時,fork()將子 PID 回傳給原始行程,將 0 回傳給子行程。失敗時,它回傳 -1 給父級(并且沒有子級)。如果事實上兩者都fork成功,那么所有結果行程的 PID 都會不同,因此唯一fork() == fork()會評估為 true 的情況是在第一個子行程的子行程中,其中兩個fork()呼叫都將回傳 0。僅在該行程中,k將增加;在其他行程中,它將遞減。
行程不共享記憶體,因此增量和減量分別反映在各個行程的單獨副本中k。沒有對各種行程運行的順序進行控制,原則上它們可以k以任何順序列印它們的值。這涵蓋了三個觀察到的輸出。
但是對于只k列印三個值的情況呢?最可能的解釋是第一個fork()成功,但在其中一個結果程序中,第二個失敗,回傳 -1。如果fork()失敗發生在原始行程中,那么第二個成功實體fork()仍將產生一個fork() == fork()評估為真的行程。另一方面,如果fork失敗發生在第一個孩子身上,那么將不會有程序fork() == fork()評估為真。這將解釋兩個三輸出結果。
就 PID 和 PPID 而言,似乎讓您感到震驚的一件事是某些行程的父行程終止的影響。一個不同于初始行程的行程總是有一個活行程作為它的父行程。如果行程的原始父行程在其自身P之前終止P,則分配一個不同的父行程;在符合 POSIX 的系統上,這將是 process 1。
因為你的程式沒有做任何事情來確保父行程的壽命比他們的孩子長,你有時會看到一些原始父母在他們的孩子之前終止的影響。這解釋了 PPID 模式的變化。但是,您似乎在一個環境(可能是某種容器)中運行您的程式,該環境(可能是某種容器)在新父級的分配細節方面不符合 POSIX,這在某種程度上掩蓋了該問題的根源。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/413765.html
標籤:
上一篇:包含別名的變數未正確展開
