现在我在理解fork()
系统调用的工作方面遇到了问题。
我写了一段代码:
#include<stdio.h>
int main()
{
int a, b;
b=fork();
printf("\n the value of b = %d",b);
}
此代码的输出如下:
现在我不明白为什么输出是这样的?
之后我只是在我的代码中添加一行,输出完全不同。 我的代码如下:
int main()
{
int a, b;
b=fork();
当我运行代码时输出如下 2389我的名字是manish
the value of b = 0
现在我对fork()
电话的工作感到困惑。
我的问题如下:
fork()
如何运作?fork()
通话后的位置?b
的输出发生在不同的地方意味着在第一个代码中
b = 2260
的输出就在输出b = 0
之前,而b = 2389
的值不在b = 0
之前?请在问题中编写的代码中解释fork的工作原理,以便我能够正确学习它。
答案 0 :(得分:39)
首先要理解为什么使用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'本身来完成它的执行。运行此程序的最终输出可能类似于:
my name is manish // executed by parent my name is anil // child the value of b = 0 // child my name is anil // parent the value of b = 2244 // parent 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
来终止。在子prcoess完成之后,父进程在waitpid
调用之后继续,开始for
循环的另一次迭代并分叉另一个(下一个)进程。这将继续,直到所有子进程按顺序执行,执行最终返回到父进程。
答案 1 :(得分:5)
fork()
被调用的位置继续执行。b
的值为0.在原始过程中,b
的值是复制过程的进程ID。答案 2 :(得分:3)
分叉由操作系统实现。它基本上创建了一个子进程,并在fork()
。
父进程接收文件进程的进程ID:b=fork();
b具有进程ID。子进程的pid为零。
(和4)因为这两个过程既可以并行运行,也可以按时间切片,因此输出会有所不同。
您可能需要查看此内容:http://en.wikipedia.org/wiki/Fork_(operating_system)
答案 3 :(得分:1)
你最好从this开始。
在这里您可以找到解释和代码示例。