首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >fork()的功能

fork()的功能
EN

Stack Overflow用户
提问于 2010-12-16 18:25:46
回答 3查看 1.3K关注 0票数 2

系统信息:我在一台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标志):

代码语言:javascript
复制
#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看起来格式正确,但对于我认为我的程序应该做的事情来说,它太大了。

任何帮助都将不胜感激。

EN

回答 3

Stack Overflow用户

发布于 2010-12-16 18:34:12

我不确定为什么要为子进程执行到stdoutfputs,也没有Unix机器来验证/测试。

但是,以下内容会跳出来:

代码语言:javascript
复制
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码作为您的deptharity,因此您的代码将尝试生成50^51进程,而不是2^3

你想要的是:

代码语言:javascript
复制
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和它的双胞胎也需要修正。

编辑虽然现在这不是问题,但是你正在sprintfobuf中的一些东西的长度已经非常接近了。让一些消息稍微长一点,至少你想要使用snprintf或者,更好的是,直接使用Kaboom!进入文件。

编辑我刚刚意识到fork,作为一个操作系统函数,很可能并不知道C I/O函数所做的内部缓冲。这就解释了为什么你会得到重复的数据(父进程和子进程都会在fork上得到缓冲数据的副本)。在循环之前尝试fflush(stdout)。也可以在每个fork之前使用fflush(ofile)

票数 6
EN

Stack Overflow用户

发布于 2010-12-16 18:57:21

您的代码中有两个错误:

1)

代码语言:javascript
复制
  int depth = *argv[2];//depth of the process tree
  int arity = *argv[3];//number of children each process should have

使用此代码,您将获得字符串argv2和argv3的第一个字符。正确的代码必须是这样的:

代码语言:javascript
复制
int depth = atoi(argv[2]);
int arity = atoi(argv[3]);

2)

代码语言:javascript
复制
bleh[0] = depth;
fputs(bleh, stdout);
bleh[0] = arity;
fputs(bleh, stdout);

你可以做类似bleh[0] = (char) depth;的事情,但是你只需要保留整数的第一个字节,而这不是你想要做的,如果你想打印整个整数,只需使用:

代码语言:javascript
复制
printf("%d\n%d", depth, arity);

我刚刚用这些修改尝试了你的代码,它似乎工作得很好:)

安徽省

票数 3
EN

Stack Overflow用户

发布于 2010-12-16 18:34:32

您不能在函数开始时使用该代码打印数字。它可能通过将非字符串传递给fputs()来调用未定义的行为。

此外,您似乎正在向文件发出文本,但它却以二进制模式打开,这似乎是错误的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4459685

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档