系统信息:我在一台2个月大的笔记本上运行64位Ubuntu 10.10。
大家好,我有一个关于C中的fork()函数的问题。从我使用的资源(Stevens/Rago、YoLinux和Opengroup)来看,我的理解是,当你派生一个进程时,父进程和子进程都会从下一个命令继续执行。由于fork()将0返回给子进程,并将子进程的进程id返回给父进程,因此您可以使用两个if语句来区分它们的行为,假设您使用pid = fork()进行了fork,则一个if(pid = 0)用于子进程,if(pid > 0)。
现在,最奇怪的事情发生了。在我的main函数的开始,我向stdout打印了几个已经分配给变量的命令行参数。这是整个程序中的第一个非赋值语句,但是,有时当我稍后在程序中调用fork时,似乎会执行这个print语句。
我的程序的目标是创建一个“进程树”,每个进程都有两个子进程,深度为3,从而创建初始可执行文件的总共14个子进程。每个进程都会在fork前后打印其父进程的进程ID和进程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“的语句有关,因为这可能会产生比预期更多的分支。
任何帮助都将不胜感激。
发布于 2010-12-16 20:35:10
调用printf时,数据存储在内部缓冲区中。当您派生时,该缓冲区由子级继承。在某个时刻(当您再次调用printf时,或者当您关闭文件时),缓冲区将被刷新,数据将写入底层文件描述符。为了防止缓冲区中的数据被子级继承,您可以在调用fork之前通过fflush刷新文件。
https://stackoverflow.com/questions/4460591
复制相似问题