系统信息:我在一台2个月大的笔记本上运行64位Ubuntu 10.10。
大家好,我有一个关于C中fork()函数的问题。根据我使用的资源(Stevens/Rago、YoLinux和Opengroup),我的理解是,当你派生一个进程时,父进程和子进程都会从下一个命令继续执行。由于fork()将0返回给子对象,并将子对象的进程id返回给父对象,因此您可以使用两个if语句来区分它们的行为,一个用于子对象的if(pid == 0)和if(pid > 0) (假设您使用pid = fork()派生)。
现在,最奇怪的事情发生了。在我的main函数的开始,我将输出到stdout,其中有几个命令行参数已经分配给了变量。这是整个程序中的第一个非赋值语句,但是,似乎每次我在程序中稍后调用fork时,都会执行这些打印语句。
我的程序的目标是创建一个“进程树”,每个进程都有两个子进程,深度为3,从而创建初始可执行文件的总共15个子进程。每个进程都会在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看起来格式正确,但对于我认为我的程序应该做的事情来说,它太大了。
任何帮助都将不胜感激。
发布于 2010-12-16 18:34:12
我不确定为什么要为子进程执行到stdout的fputs,也没有Unix机器来验证/测试。
但是,以下内容会跳出来:
int depth = *argv[2];//depth of the process tree
int arity = *argv[3];//number of children each process should have您将argv[2]和argv[3]中第一个字符的ASCII码作为您的depth和arity,因此您的代码将尝试生成50^51进程,而不是2^3。
你想要的是:
int depth = atoi(argv[2]);//depth of the process tree
int arity = atoi(argv[3]);//number of children each process should have一旦你解决了这个问题,bleh[0] = depth和它的双胞胎也需要修正。
编辑虽然现在这不是问题,但是你正在sprintf到obuf中的一些东西的长度已经非常接近了。让一些消息稍微长一点,至少你想要使用snprintf或者,更好的是,直接使用Kaboom!进入文件。
编辑我刚刚意识到fork,作为一个操作系统函数,很可能并不知道C I/O函数所做的内部缓冲。这就解释了为什么你会得到重复的数据(父进程和子进程都会在fork上得到缓冲数据的副本)。在循环之前尝试fflush(stdout)。也可以在每个fork之前使用fflush(ofile)。
发布于 2010-12-16 18:57:21
您的代码中有两个错误:
1)
int depth = *argv[2];//depth of the process tree
int arity = *argv[3];//number of children each process should have使用此代码,您将获得字符串argv2和argv3的第一个字符。正确的代码必须是这样的:
int depth = atoi(argv[2]);
int arity = atoi(argv[3]);2)
bleh[0] = depth;
fputs(bleh, stdout);
bleh[0] = arity;
fputs(bleh, stdout);你可以做类似bleh[0] = (char) depth;的事情,但是你只需要保留整数的第一个字节,而这不是你想要做的,如果你想打印整个整数,只需使用:
printf("%d\n%d", depth, arity);我刚刚用这些修改尝试了你的代码,它似乎工作得很好:)
安徽省
发布于 2010-12-16 18:34:32
您不能在函数开始时使用该代码打印数字。它可能通过将非字符串传递给fputs()来调用未定义的行为。
此外,您似乎正在向文件发出文本,但它却以二进制模式打开,这似乎是错误的。
https://stackoverflow.com/questions/4459685
复制相似问题