Thread: Problem with forking a process

  1. #1
    Registered User
    Join Date
    Sep 2007
    Posts
    5

    Problem with forking a process

    Hello all,
    I am try to see how forking the process works. I am having some problem with the code I have written :


    Code:
    #include <stdio.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <stdlib.h>
    
    childprocess(int pid, int pnum);
    main () {
    	int pid, pid0, pid1, status, FD, coremaker, tochild[2], toparent[2];
    	FD = creat("new file.txt", S_IRWXU);
    	if((pid = fork()) < 0) {
    		printf("Could not fork process");
    	} else {
    		if(pid !=0)
    			printf("\nProcess forked");
    	}
    	
    	if(pid == 0) childprocess(pid,1);
    	//if(pid != 0) {
    	
    	pid = wait(&status);
    	printf("\nProcess (id %d ) exited ", pid);
    		
    	//}
    	
    	if((pid = fork()) < 0) {
    		printf("Could not fork second process");
    	}else{
    		if(pid !=0)
    			printf("\nSecond process forked");
    	}	
    	if(pid == 0) childprocess(pid,2);
    	
    //	if(pid != 0) {
    		pid = wait(&status);
    		printf("\nProcess (id %d ) exited " , pid);
    //	} 
    	close(FD);
    	coremaker = 1/0; // SIGFPE to produce the core file
    	exit(0);
    }
    
    childprocess(int pid, int pnum) {
    	float i = 0;
    	int index = 0;
    	for(index = 0; index < 900; index++) {
    	}
    	//printf("\nPID %d matches index : %d", pid, pnum); 
    	exit(0);
    }
    I xpect the parent process to fork and wait for the second process to exit which goes to the function childprocess where it exits. Then the process should print on the terminal "Process id <child process id> terminated". Then it should fork again and do the same with the second chid process.

    However the output is as follows :


    Process forked
    Process (id 16237 ) exited Process (id 16237 ) exited
    Second process forked
    Floating point exception (core dumped)


    That is, I get the floating point exception before I get the message that the second child process has also exited.

    When I comment out the division by zero, I get the followng output :


    Process forked
    Process (id 16324 ) exited Process (id 16324 ) exited
    Second process forked
    Process (id 16325 ) exited

    Here I get the message, that the first child proces has exited, two times.
    This seems a little strange. Please help me with it
    Dhruv

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Following a fork(), where both the parent and child write to stdout (or any other shared descriptor for that matter), you can't make any assumptions about what order things happen in.

    They're two independent processes, so the OS can choose to run either of them at any time.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Sep 2007
    Posts
    5
    HI Salem,
    thanks for the point, but the child process should not even access the stdout , as it goes to the function childprocess where it eventually exits , therefore it should not print the lines " Process id <child process id> exited" or cause the floating point exception.

  4. #4
    Sasquatch mog's Avatar
    Join Date
    Dec 2006
    Location
    Caves of Narshe
    Posts
    16
    Code:
    if (pid == 0)
    {
        child(1, 2);
        //
        // And here everything proceed as normal.. At least in your code, because you dont use any return-statement "or" "else"..
        //
    }
    Last edited by mog; 09-30-2007 at 04:06 PM.

  5. #5
    Registered User
    Join Date
    Sep 2007
    Posts
    5
    Mog , I could not quiet understand what you meant. Did you mean that in my code , both the parent and the child should go through the print statements and the rest of the code, I think oly the parent should have?

  6. #6
    Sasquatch mog's Avatar
    Join Date
    Dec 2006
    Location
    Caves of Narshe
    Posts
    16
    Maybe this will help you understand.

    Code:
    #include <sys/types.h>
    #include <unistd.h>
    
    int main(int argc, char *argv[])
    {
        pid_t pid;
    
        pid = fork();
    
        if (pid < 0)
        {
            printf("Fork failed\n");
            return 0;
        }
        if (pid == 0)
        {
            printf("Forked\n");
            return 0;
        }
        
        wait(pid);
        
        printf("Main\n");
        return 0;
    }
    Last edited by mog; 10-01-2007 at 07:24 AM.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Unitedroad View Post
    HI Salem,
    thanks for the point, but the child process should not even access the stdout , as it goes to the function childprocess where it eventually exits , therefore it should not print the lines " Process id <child process id> exited" or cause the floating point exception.
    You are not flushing the output from printf(), and it doesn't end with a newline (which implies a flush in many C-libraries, but there's no absolute guarantee).
    Code:
    		pid = wait(&status);
    		printf("\nProcess (id %d ) exited " , pid);
    Since an exception like the "floating point" exception you get is a fatal error, the application won't necessarily flush buffers for you like it does when you use for example "exit" to end your application.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User
    Join Date
    Sep 2007
    Posts
    5
    So matsp, this means then that when the child process is terminated with exit call , it flushes out the output , so what was there in the printf statement that was already to be printed by the parent process gets printed again when the child makes the exit system call? And in the scenario where the parent process does the floating point exception , its buffer does not get printed as it has not been flushed as we got floating point exception which does not flush buffers as it is done when the process calls the exit system call?

    But in the first case the data in the buffer is already printed by the parent so howcome it is still there in the child process buffer? Do they share the same buffer or separate identical copies of the buffer ? So then when the child comes to the exit statement, it flushes the buffer and when the parent comes to the printf statement , "Second process forked", it flushes its own buffer which has the same text.

    While in the code with the floating point exception , the parent does not get the chance to flush its buffer at all.

    Please help me further.

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    In a fork, anything written by the child process will be the childs own - it uses a process called "copy on write", which means that all memory in the child process is a read-only copy of the parent. Whenever a piece of memory is written to, the kernel gets a page-fault (write on a read-only page violation), which it "fixes" by making a copy of the relevant page of memory, and then returning to the user-process that continues the execution where it stoped (finishing the write to memory).

    Of course, if there is some unflushed data in the parent, then it will be flushed by both the parent and child. A child process flushing it's stdout would not affect what is in the parent-process.

    An "emergency exit" as it would be in the case of a fault such as the math operation, will not exit in the standard way [although exactly how this works is implementation dependant].

    You could use stderr instead of stdout if you want to ensure that your prints are processed "immediately" rather than buffered. Or add fflush(stdout) after each printf (and in particular, use a fflush(stdout) before fork).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    1. Before a fork, you should always fflush() all output streams.
    2. Put '\n' at the END of the lines you print, not the beginning. And ALWAYS use it.

    I see nothing else wrong.

  11. #11
    Registered User
    Join Date
    Sep 2007
    Posts
    5
    Hi everyone,
    thanks alot explaining me all the reasons why I wasn't seeing the output of this program as I expected it to be. Thanks alot for the patience through which you helped me understand these concepts very clearly. I knew of these concepts before but could not comprehend them coming in here because I had never seen it any output yet , so coming to this forum has really turned out to be very good for me.
    Last edited by Unitedroad; 10-04-2007 at 01:50 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 9
    Last Post: 03-20-2009, 05:22 PM
  2. Check number of times a process is running
    By linuxwolf in forum Windows Programming
    Replies: 6
    Last Post: 10-17-2008, 11:08 AM
  3. Bin packing problem....
    By 81N4RY_DR460N in forum C++ Programming
    Replies: 0
    Last Post: 08-01-2005, 05:20 AM
  4. process semaphores cleanup problem
    By code_quasher in forum Linux Programming
    Replies: 1
    Last Post: 05-19-2005, 10:57 AM
  5. Problem using java programs within C code
    By lemania in forum Linux Programming
    Replies: 1
    Last Post: 05-08-2005, 02:02 AM