C语言 c语言中fork的工作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6210638/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
working of fork in c language
提问by Golu
Now I have a problem in understanding the working of fork()system call.
I write a code which is following :
现在我在理解fork()系统调用的工作方面遇到了问题。我写了一个代码,如下:
#include<stdio.h>
int main()
{
int a, b;
b=fork();
printf("\n the value of b = %d",b);
}
The output of this code is following :
此代码的输出如下:
Now I don't understand why the output is like this ?
现在我不明白为什么输出是这样的?
After that i just add a line to my code and output is completely different. my code is following:
之后,我只是在我的代码中添加了一行,输出就完全不同了。我的代码如下:
int main()
{
int a, b;
b=fork();
When i run the code the output is following 2389my name is manish
当我运行代码时,输出跟随 2389my name is manish
the value of b = 0
Now I'm totally confused about the working of fork()call.
现在我对fork()通话的工作完全感到困惑。
My question are following:
我的问题如下:
- How
fork()works? - Where the control goes after the
fork()call? - Can any body explain why the outputs of codes written in problem?
- Why the output of
boccurring at different places means in first code the output ofb = 2260is just before the outputb = 0while the value ofb = 2389is not just before theb = 0?
- 如何
fork()运作? fork()调用后控制权在哪里?- 任何机构都可以解释为什么编写的代码输出有问题吗?
- 为什么
b在不同地方出现的输出意味着在第一个代码中的输出b = 2260正好在输出之前,b = 0而 的值b = 2389不只是在输出之前b = 0?
Please explain me the working of fork in the code written in the problem so that I can learn it properly .
请在问题中编写的代码中解释fork的工作原理,以便我可以正确学习。
回答by ladaghini
It might help to first understand why the word fork was used to name this function. Ever heard of a "fork on the road?" At a fork, the process has to split paths.
首先了解为什么使用 fork 这个词来命名这个函数可能会有所帮助。听说过“路上的岔路口”吗?在分叉处,进程必须分割路径。
First there is a single process executing normally until you reach the forkcall. When fork is called, a new process is created, which is identical in virtually every way as the original process, except for the return value of the fork function.The newly created process is called the child process, and hence the process that spawned it is referred to as the parent process.
首先,只有一个进程正常执行,直到您到达fork呼叫为止。当 fork 被调用时,会创建一个新进程,除了 fork 函数的返回值之外,它几乎在所有方面都与原始进程相同。新创建的进程称为子进程,因此产生它的进程称为父进程。
Since you'd want to perform different tasks for each branch of the fork, it necessitates that you be able to distinguish the child process from the parent process. That's where the return value of forkcomes in: forkreturns the process id (pid) of the child (the newly created process) to the parent; it returns 0 to the child. Also, should the execution of forkgo wrong, the return value is -1.
由于您希望为 fork 的每个分支执行不同的任务,因此您必须能够区分子进程和父进程。这就是返回值的fork用武之地:fork将子进程(新创建的进程)的进程 ID(pid)返回给父进程;它返回 0 给孩子。另外,如果执行fork出错,返回值为-1。
In your code, you don't distinguish between the child and parent process, so both processes run the entire code that follows after the forkcall.
在您的代码中,您不区分子进程和父进程,因此两个进程都运行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);
}
As you can see, both processes have the same code following the fork, hence the output is repeated. Perhaps if you want the parent process to output Manish and the child to output Anil, then you can do something like:
如您所见,两个进程在 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;
}
Finally, the last comment that must be made is that in your code, the output appears to have been executed first by one process in its entirety and then the other process in its entirety. That may not always be the case. For example, the operating system might allow the parent to execute the 'manish' output, then make this process wait, and handing the cpu over to the child process, which then executes 'manish'. However, the child process may continue and execute 'anil' and 'b' outputs, completing execution of the child process and thus returning execution back to the parent process. Now the parent finishes its execution by outputting 'anil' and 'b' itself. The final output of running this program may look something like:
最后,必须做出的最后一条注释是,在您的代码中,输出似乎首先由一个进程整体执行,然后由另一个进程整体执行。情况可能并非总是如此。例如,操作系统可能允许父进程执行“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:~$
Take a look at the man page for fork.
Also look at waitpidfor proper handling of child processes by parent processes so you don't create zombies.
查看fork. 还要查看waitpid父进程对子进程的正确处理,以免创建僵尸。
Edit: In response to your questions in the comments, I'll answer how you can simply run each process consecutively.
编辑:针对您在评论中提出的问题,我将回答您如何简单地连续运行每个进程。
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;
}
Of course, isn't the best code, but it's just to illustrate the point. The big idea here is the waitpidcall, which causes the parent process to wait until the child process it just forked to terminate. After the child prcoess completes, the parent continues after the waitpidcall, starting another iteration of the forloop and forking another (the next) process. This continues until all child process have executed sequentially and execution finally returns to the parent.
当然,这不是最好的代码,但只是为了说明这一点。这里的主要思想是waitpid调用,它导致父进程等待它刚刚fork结束的子进程。子进程完成后,父进程在waitpid调用后继续,开始循环的另一次迭代for并分叉另一个(下一个)进程。这一直持续到所有子进程都按顺序执行并且执行最终返回到父进程。
回答by Chris Frederick
- Fork creates a copy of your current process.
- Both the original and the copy continue executing from the point at which
fork()was called. - Because your code is executed twice, your print statements are also evaluated twice. In the copied process, the value of
bis 0. In the original process, the value ofbis the process ID of the copied process. - Once your processes start running concurrently, they will be scheduled independently by your operating system and thus you have no guarantees about when they will actually be run.
- Fork 创建当前进程的副本。
- 原始和副本都从
fork()被调用的点继续执行。 - 因为你的代码被执行了两次,所以你的打印语句也被评估了两次。在被复制的进程中, 的值为
b0。在原进程中, 的值为b被复制进程的进程ID。 - 一旦您的进程开始并发运行,它们将由您的操作系统独立调度,因此您无法保证它们何时实际运行。
回答by Richard Schneider
Forking is implemented by the OS. It basically creates a child process and starts running it after the
fork().The parent process receives the process id of the file process:
b=fork();b has the process id. The child process get a pid of zero.(and 4) Because both process can either run in parallel or be time sliced, your output will vary.
分叉是由操作系统实现的。它基本上创建了一个子进程并在
fork().父进程接收文件进程
b=fork();的进程id :b 有进程id。子进程的 pid 为零。(和 4)因为这两个过程既可以并行运行,也可以进行时间切片,所以您的输出会有所不同。
You may want to check this out: http://en.wikipedia.org/wiki/Fork_(operating_system)
你可能想看看这个:http: //en.wikipedia.org/wiki/Fork_(operating_system)

