gpt4 book ai didi

c - fork 和流程管理

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:25:28 25 4
gpt4 key购买 nike

系统信息:我在 2 个月大的笔记本电脑上运行 64 位 Ubuntu 10.10。

大家好,我有一个关于 C 中的 fork() 函数的问题。根据我使用的资源(Stevens/Rago、YoLinux 和 Opengroup),我的理解是当你 fork 一个进程时,两者 parent 和 child 从下一个命令继续执行。由于 fork() 将 0 返回给子进程,而子进程的进程 ID 返回给父进程,因此您可以使用两个 if 语句来区分它们的行为,一个 if(pid = 0) 用于子进程,而 if(pid > 0),假设你用 pid = fork() fork 了。

现在,我遇到了最奇怪的事情。在我的 main 函数的开头,我将几个已分配给变量的命令行参数打印到 stdout。这是整个程序中的第一个非赋值语句,然而,似乎有时当我在程序后面调用 fork 时,会执行这个 print 语句。

我的程序的目标是创建一个“进程树”,每个进程有两个子进程,深度为 3,从而创建初始可执行文件的总共 14 个子进程。每个进程打印其父进程 ID 及其 fork 前后的进程 ID。

我的代码如下并且有适当的注释,命令行参数应该是“ofile 3 2 -p”(我还没有实现 -p/-c 标志):

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


int main (int argc, char *argv[])
{
if(argc != 5)//checks for correct amount of arguments
{
return 0;
}

FILE * ofile;//file to write to
pid_t pid = 1;//holds child process id
int depth = atoi(argv[2]);//depth of the process tree
int arity = atoi(argv[3]);//number of children each process should have

printf("%d%d", depth, arity);

ofile = fopen(argv[1], "w+");//opens specified file for writing



int a = 0;//counter for arity
int d = 0;//counter for depth
while(a < arity && d < depth)//makes sure depth and arity are within limits, if the children reach too high(low?) of a depth, loop fails to execute
//and if the process has forked arity times, then the loop fails to execute
{
fprintf(ofile, "before fork: parent's pid: %d, current pid: %d\n", getppid(), getpid());//prints parent and self id to buffer
pid = fork(); //forks program
if(pid == 0)//executes for child
{
fprintf(ofile, "after fork (child):parent's pid: %d, current pid: %d\n", getppid(), getpid());//prints parent's id and self id to buffer
a=-1;//resets arity to 0 (after current iteration of loop is finished), so new process makes correct number of children
d++;//increases depth counter for child and all of its children
}
if(pid > 0)//executes for parent process
{
waitpid(pid, NULL, 0);//waits on child to execute to print status
fprintf(ofile, "after fork (parent):parent's pid: %d, current pid: %d\n", getppid(), getpid());//prints parent's id and self id to buffer
}
a++;//increments arity counter
}


fclose(ofile);
}

当我运行“gcc main.c -o ptree”然后“ptree ofile 3 2 -p”时,控制台中出现了几次“32”垃圾邮件,文件“ofile”的格式看似正确,但是对于我认为我的程序应该做的事情来说有点太大了,显示 34 个子进程,而应该有 2^3+2^2+2^1=14。我认为这在某种程度上与打印“32”的语句有关,因为这似乎可能产生比预期更多的 fork 。

如有任何帮助,我们将不胜感激。

最佳答案

当您调用 printf 时,数据存储在内部缓冲区中。当您 fork 时,该缓冲区由 child 继承。在某些时候,(当您再次调用 printf 时,或者当您关闭文件时),缓冲区被刷新并且数据被写入底层文件描述符。为了防止缓冲区中的数据被 child 继承,您可以在调用 fork 之前通过 fflush 刷新 FILE *。

关于c - fork 和流程管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4460591/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com