2016-12-29 40 views
0

我想了解「fork」是如何工作的。我寫了一個小程序來搞清楚,但執行對我來說似乎很奇怪。事實上,「最大最終」出現了幾次,而它高於遞歸調用的「計算」函數。你能解釋爲什麼嗎?試圖瞭解c中的fork()行爲

下面是代碼:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <fcntl.h> 

ecrire_fils(int nb, char* name) // function to write in a file 
{ 
    ... 
} 

lire_pere(int* j, char* name) // function to read a file 
{ 
    ... 
} 

int max(int * tab, int debut, int fin) // find the max in an array 
{ 
    .. 

} 


int tab[] = {2,4,5,4,1,2,1,2,255,125}; 
int seuil = 3; 
int maximum; 



int compute(int * tab, int debut, int fin); 

int main(){ 

    printf("\n \n maximum final: %d", compute(tab, 0,9)); 

    return 0; 

} 


int compute(int * tab, int debut, int fin) { 

    int pid1, pid2, status; 
    int milieu = (fin + debut) /2; 
    char name1[20] = "fic1_"; 
    char name2[20] = "fic2_"; 
    char buffer[100]; 
    sprintf(buffer, "%d", getpid()); 
    strcat(name1, buffer); 
    strcat(name2, buffer); 

    if (fin - debut <= seuil) // recherche séquentielle du max 
     return max(tab, debut, fin); // on s'arrête là et on renvoit le maximum: on n'écrit pas dans un fichier et aucun fichier ne sera lu 




    pid1 = fork(); 
    if (pid1 == 0) // actions fils1, s'occupe du debut au milieu 
    { 
     maximum = compute(tab, debut, milieu); // on récupère la valeur du max des fils 
     sleep(1); 

     ecrire_fils(maximum, name1); // on écrit cette valeur dans un fichier qui sera lu par le père 

    } 
    else 
    { 
     pid2 = fork(); 
     if (pid2 == 0) // actions fils2, s'occupe du milieu à la fin 
     { 
      maximum = compute(tab, milieu, fin); 
      sleep(1); 
      // on écrit le résultat dans le fichier 
      ecrire_fils(maximum, name2); 


     } 
     else // actions père 
     { 
      int j1 = 0, j2 = 0; 

      waitpid(pid1, &status, 0); 
      lire_pere(&j1, name1); 

      waitpid(pid2, &status, 0); 
      lire_pere(&j2, name2); 

      printf("\n fils1: %d, fils2: %d (début = %d milieu = %d fin =%d)", j1, j2, debut, milieu, fin); 
      sleep(1); 


      if (j1>j2) 
       return j1; 
      return j2; 

     } 

    } 

} 
+0

由於孩子似乎沒有退出,除了通過返回,三個進程中的每一個都應該從主打印中打印某些內容。你還沒有創建一個MCVE([MCVE]),因爲你的代碼中有不完整的函數,所以很難知道還有什麼是kn。 –

回答

0

首先出現的是,直到你到達fork調用正常執行一個單一的過程。 當調用fork時,會創建另一個新進程,除了fork函數的返回值之外,它幾乎與原始進程相同。新創建的進程稱爲子進程,因此生成該進程的進程稱爲父進程。

由於您希望爲每個分支的分支執行不同的任務,因此您必須能夠將子進程與父進程區分開來。 fork返回子進程ID(PID)(新創建的進程)父進程

+0

謝謝!我認爲由fork()創建的子只包含fork()函數之後的代碼。但它也複製主要功能? – Sheep

+0

是的,它複製並創建另一個過程,如果你明白我的答案,然後接受這一點。 –

+0

好的:)。我怎麼做只能執行一次主函數的內容?如果我把它放在一個if中,它是cgonna被稱爲每個「父親」,因爲它是遞歸的... – Sheep

1

一個從您的評論MCVE(帶小的修改):

#include <stdio.h> 
#include <unistd.h> 

int main() 
{ 
    printf("\n %d : pouet", getpid()); 
    int pid = fork(); 
    printf("\n %d : plop", getpid()); 
    if (pid >0) 
    printf("\n %d : chouette", getpid()); 
    printf("\n"); 
    return 0; 
} 

家長打印pouet並沒有按」 t刷新緩衝區(嚴格來說,這是部分刷新 - 這就是爲什麼你只看到一個空行在輸出的開始)。孩子繼承父母的確切副本,包括任何遺留在緩衝區中的內容。當孩子打印的時候,這些內容也被打印出來。

請注意,如果將格式字符串從"\n..."更改爲"...\n",該示例將按預期工作。