开发者

Forking and Process Management

System information: I am running 64bit Ubuntu 10.10 on a 2 month old laptop.

Hi everyone, I've got a question about the fork() function in C. From the resources I'm using (Stevens/Rago, YoLinux, and Opengroup) it is my understanding that when you fork a process, both the parent and child continue execution from the next command. Since fork() returns 0 to the child, and the process id of the child to the parent, you can diverge their behavior with two if statements, one if(pid = 0) for the child and if(pid > 0), assuming you forked with pid = fork().

Now, I am having the weirdest thing occur. At the beginning of my main function, I am printing to stdout a couple of command line arguments that have been assigned to variables. This is this first non assignment statement in the entire program, yet, it would seem that sometimes when I call fork later in the program, this print statement is executed.

The goal of my program is to create a "process tree" with each process having two children, down to a depth of 3, thus creating 14 total children of the initial executable. Each process prints its parent's process ID and its process ID before and after the fork.

My code is as follows and is properly commented, command line arguments should be "ofile 3 2 -p" (i haven't gotten to implementing -p/-c flags yet":

#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开发者_如何学Python 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);
}

When I run "gcc main.c -o ptree" then "ptree ofile 3 2 -p", the console is spammed with "32" a few times, and the file "ofile" is of seemingly proper format, but a bit too large for what I think my program should be doing, showing 34 child processes, when there should be 2^3+2^2+2^1=14. I think this is somehow related to the statement that is printing "32", as that would seem to possibly spawn more forks than intended.

Any help would be greatly appreciated.


When you call printf, the data is stored in a buffer internally. When you fork, that buffer is inherited by the child. At some point, (when you call printf again, or when you close the file), the buffer is flushed and data is written to the underlying file descriptor. To prevent the data in the buffer from being inherited by the child, you can flush the FILE * before you call fork, via fflush.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜