首先理解为什么使用 fork 这个词来命名这个函数可能会有所帮助。听说过“岔路口”吗?在分叉处,该过程必须拆分路径。
首先,有一个进程正常执行,直到您到达fork
呼叫为止。当调用 fork 时,会创建一个新进程,除了 fork 函数的返回值之外,它几乎在所有方面都与原始进程相同。新创建的进程称为子进程,因此产生它的进程称为父进程。
由于您希望为 fork 的每个分支执行不同的任务,因此您必须能够将子进程与父进程区分开来。这就是返回值的fork
来源:fork
将子进程(新创建的进程)的进程id(pid)返回给父进程;它返回 0 给孩子。另外,如果执行fork
出错,返回值为-1。
在您的代码中,您不区分子进程和父进程,因此两个进程都运行fork
调用之后的整个代码。
//what the child process looks like after fork is called
int main()
{
int a, b;
b=fork(); // <-- current line of execution: 0 is returned to b
printf("\nmy name is manish\n");
printf("\n my name is anil\n");
printf("\n the value of b = %d",b);
}
// what the parent process looks like after fork is called
int main()
{
int a, b;
b=fork(); // <-- current line: child process id is returned
printf("\nmy name is manish\n");
printf("\n my name is anil\n");
printf("\n the value of b = %d",b);
}
如您所见,两个进程在 fork 之后具有相同的代码,因此重复输出。也许如果您希望父进程输出 Manish 而子进程输出 Anil,那么您可以执行以下操作:
int main()
{
pid_t b; // note that the actual return type of fork is
// pid_t, though it's probably just an int typedef'd or macro'd
b = fork();
if (b == -1) perror("Fork failed");
else if (b > 0) {
printf("My name is Manish\n"); // parent process
else
printf("My name is Anil\n"); // child process
printf("The value of b is %d\n", b);
return 0;
}
最后,必须做的最后一条评论是,在您的代码中,输出似乎首先由一个进程整体执行,然后由另一个进程整体执行。情况可能并非总是如此。例如,操作系统可能允许父进程执行“manish”输出,然后让该进程等待,并将 cpu 交给子进程,然后子进程执行“manish”。但是,子进程可以继续执行“anil”和“b”输出,完成子进程的执行,从而将执行返回给父进程。现在父母通过输出'anil'和'b'本身来完成它的执行。运行此程序的最终输出可能类似于:
我的名字是 manish // 由父母执行
我的名字是阿尼尔//孩子
b = 0 的值 // 孩子
我的名字是阿尼尔//父母
b = 2244 的值 // 父级
manish.yadav@ws40-man-lin:~$
看一下手册页fork
。还要查看waitpid
父进程对子进程的正确处理,以免创建僵尸。
编辑:为了回答您在评论中的问题,我将回答您如何简单地连续运行每个流程。
int main()
{
pid_t pid;
int i;
for (i=0; i<NUM_PROCESSES; i++)
{
pid = fork();
if (pid == -1)
{
perror("Error forking");
return -1;
}
else if (pid > 0)
{
// parent process
waitpid(-1, NULL, 0); //might want to look at man page for this
// it will wait until the child process is done
}
else
{
// do whatever each process needs to do;
// then exit()
doProcess(i);
exit(0);
}
}
// do anything else the parent process needs to do
return 0;
}
当然,不是最好的代码,但这只是为了说明这一点。这里的主要想法是waitpid
调用,它会导致父进程等到它刚刚fork
编辑的子进程终止。子进程完成后,父进程在waitpid
调用后继续,开始循环的另一个迭代for
并分叉另一个(下一个)进程。这一直持续到所有子进程都已按顺序执行并且执行最终返回到父进程。