我试图理解“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 :(得分: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
并且不刷新缓冲区(严格来说,它是部分刷新 - 这就是为什么在输出开头只看到一个空行)。子项继承父项的精确副本,包括stdout
缓冲区中剩余的内容。当孩子打印时,也会打印这些内容。
请注意,如果您将格式字符串从"\n..."
更改为"...\n"
,则该示例将按预期工作。
答案 1 :(得分:0)
首先有一个进程正常执行,直到你到达fork调用。 当调用fork时,会创建另一个新进程,除了fork函数的返回值之外,它几乎与原始进程完全相同。新创建的进程称为子进程,因此生成它的进程称为父进程。
由于您希望为fork的每个分支执行不同的任务,因此您必须能够将子进程与父进程区分开来。 fork
将子进程的id(pid)(新创建的进程)返回给父进程