Thread: C Processing Issues (oh fork()!)

  1. #1
    Registered User
    Join Date
    Feb 2010
    Posts
    25

    C Processing Issues (oh fork()!)

    Hi. I'm a product of the "new" generation of computer science students. Meaning, I was taught Java up until college, then I learned a bit of Assembly, and now that I'm in my senior year, I'm getting the crap kicked out of me because a) Java doesn't cover many bases such as addresses, garbage collection, and all the other things that seem to be essential to the fundamentals of programming languages and b) Java seems to be very complex when it comes to such machine-close operations such as using threads and processes.

    Anyway, the good thing about this year is that I'm learning about 7 languages between my classes -- but there is a lot of stuff I don't know how to do.

    Just like fork().

    All the examples (in my textbook and online) seem to just fork() the parent process into having one child.

    I have an assignment due that requires me to create 8 processes. 3 of the processes are supposed to have 2 children each.

    What I can't seem to wrap my head around is how to keep tabs of which process you are currently using! Logically, my mind tells me to create the parents first, and have their children create children. But the code for processes is bizarre!

    Code:
    #include <sys/types.h>
    #include <stdio.h>
    #include <unistd.h>
    
    int main()
    {
    	int pid = fork();
    	  if (pid > 0)
    	  {
    		printf ("I'm the parent!  I just created child pid (%d)!\n", pid);
    	  }
    	  else if (pid == 0)
    	  {
    		printf ("I'm the child!  My pid is (%d)\n", getpid ());
    	  }
    	  else if (pid < 0)
    	  {
    		perror ("Ouch!  Unable to fork() child process!\n");
    		exit (1);
    	  }
    		return 0;
    }
    While I get this, I don't understand which process is currently being looked at. I also don't know how to make grandchildren. I don't know where to place the fork() calls, or even how to do it. I can't find any good examples online (I've been searching for 3 hours!).

    I don't want my homework done for me, I just need to learn how to determine which process I'm currently on, and how to work from there. It's a very abstract concept compared to the rest of the OOP stuff I've done before. I'm extremely stuck....

    Thanks for any and all help.

    Edit: Looking at the code I'm understanding how pid changes, but I'm still confused as to how I work it into those if statements, and how to make grandchildren with those if statements.
    Last edited by CheckMyBrain; 02-07-2010 at 08:03 PM.

  2. #2
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875
    Quote Originally Posted by CheckMyBrain View Post
    Hi. I'm a product of the "new" generation of computer science students. Meaning, I was taught Java up until college, then I learned a bit of Assembly, and now that I'm in my senior year, I'm getting the crap kicked out of me because a) Java doesn't cover many bases such as addresses, garbage collection, and all the other things that seem to be essential to the fundamentals of programming languages and b) Java seems to be very complex when it comes to such machine-close operations such as using threads and processes.

    Anyway, the good thing about this year is that I'm learning about 7 languages between my classes -- but there is a lot of stuff I don't know how to do.

    Just like fork().

    All the examples (in my textbook and online) seem to just fork() the parent process into having one child.

    I have an assignment due that requires me to create 8 processes. 3 of the processes are supposed to have 2 children each.

    What I can't seem to wrap my head around is how to keep tabs of which process you are currently using! Logically, my mind tells me to create the parents first, and have their children create children. But the code for processes is bizarre!

    Code:
    #include <sys/types.h>
    #include <stdio.h>
    #include <unistd.h>
    
    int main()
    {
    	int pid = fork();
    	  if (pid > 0)
    	  {
    		printf ("I'm the parent!  I just created child pid (%d)!\n", pid);
    	  }
    	  else if (pid == 0)
    	  {
    		printf ("I'm the child!  My pid is (%d)\n", getpid ());
    	  }
    	  else if (pid < 0)
    	  {
    		perror ("Ouch!  Unable to fork() child process!\n");
    		exit (1);
    	  }
    		return 0;
    }
    While I get this, I don't understand which process is currently being looked at. I also don't know how to make grandchildren. I don't know where to place the fork() calls, or even how to do it. I can't find any good examples online (I've been searching for 3 hours!).

    I don't want my homework done for me, I just need to learn how to determine which process I'm currently on, and how to work from there. It's a very abstract concept compared to the rest of the OOP stuff I've done before. I'm extremely stuck....

    Thanks for any and all help.

    Edit: Looking at the code I'm understanding how pid changes, but I'm still confused as to how I work it into those if statements, and how to make grandchildren with those if statements.
    Keeping track of them can be solved with three simple words: IPC. Exactly what that translates to depends on your OS but UNIX has a variety from sockets to pipes to message queues and more.

    One thing that would help with this part is what level of control are you looking for (lots of data back and forth between the parent and child process or just a simple boolean flag saying "run/don't run")...

    But one thing you may want to think about is the difference between threads and processes...it sounds like processes *might* be a little heavy-handed for what you are trying to do...but if your assignment is to do fork()s then I would suggest a volume on POSIX functionality; everything you need is there....
    C/C++ Environment: GNU CC/Emacs
    Make system: CMake
    Debuggers: Valgrind/GDB

  3. #3
    Registered User
    Join Date
    Feb 2010
    Posts
    25
    I just finished my thread project, lol.

    The project is simple. Each process outputs it's parent's PID, it's PID and it's children's PID. The problem is, I just don't know how to call fork() twice to make a parent have two children.

    I think I can easily do this if I make an array of 8 ints, call fork() 8 times (because I know P1 should have P2 and P3 as it's children), but I don't know how to create the parental heirarchy.

    It goes as follows:

    P1 gives birth to P2 and P3
    P2 births P4 and P5
    P3 births P6
    P5 births P7 and P8

    What I'm gathering is when I call fork(), the PID is increased by 1, right? So then how do you make grandchildren? I'm thinking of jerry-rigging this so that it works according to the problem, but then I'm completely missing the point of the project.

  4. #4
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875
    OK fork() it is...and fork() isn't all that tricky in typical situations (server spins off 1-n new processes to handle a common task/connection/whatever). Your situation sounds pretty academic but also sounds more like a question of logic control than process control but I could be wrong. Tell me:
    1. What do the child procs need to do beyond spin off more procs in some fiendish manner?
    2. Exactly who needs to control whom (like does the master parent process need to control all children and grandchildren or does each parent control the child proc)?
    C/C++ Environment: GNU CC/Emacs
    Make system: CMake
    Debuggers: Valgrind/GDB

  5. #5
    Registered User
    Join Date
    Feb 2010
    Posts
    25
    Honestly, no one needs to control anyone.

    I've been thinking, I've done something like this in Data Structures. Well, with leafs and stems. I just can't get a good starting point here.

    I messed around with an int[8]:
    Code:
    int main()
    {
    	int pid = fork();
    	int archy[8];
    	int i;
    	for(i = 0; i < 8; i++)
    		archy[0] = pid;
    		pid = fork();
    	for(i = 0; i < 8; i++)
    		printf("My pid is (%d)\n", archy[i]);
    But it print out:
    Code:
    My pid is (16896)
    My pid is (0)
    My pid is (0)
    My pid is (0)
    My pid is (0)
    My pid is (-12712024)
    My pid is (-12841524)
    My pid is (0)
    My pid is (0)
    My pid is (0)
    My pid is (0)
    My pid is (0)
    My pid is (0)
    My pid is (0)
    My pid is (0)
    My pid is (0)
    My pid is (0)
    My pid is (0)
    My pid is (-12712024)
    My pid is (-12712024)
    My pid is (-12841524)
    My pid is (16896)
    My pid is (0)
    My pid is (0)
    I guess at this point I'm thinking I need to make the 8 processes first, in order, put the PID in an array and then work on the structure, but I need help with this first. I can probably do the children myself...

    I'm so lost.

  6. #6
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875
    If Fork, Exec and Process control doesn't get you going I will try to give you a more specific example...
    eating dinner ATM
    C/C++ Environment: GNU CC/Emacs
    Make system: CMake
    Debuggers: Valgrind/GDB

  7. #7
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875
    if all you had to do is report proc IDs then you probably just need a single mutex-protected printPID(int PID) function that prints the process ID via cout, printf, whatever. Call as needed from within each forked process. As for controlling who has kids and who doesn't, a simple mutex-protected data structure/variable indicating the current logical process being spun (1-8) and inside the child proc a switch or just a check to see if it is process 2, 3, whatever and if so, call fork() again.

    This is off the top of my head whilst eating though...
    C/C++ Environment: GNU CC/Emacs
    Make system: CMake
    Debuggers: Valgrind/GDB

  8. #8
    Registered User
    Join Date
    Feb 2010
    Posts
    25
    Thanks. I'm going to read it and then call it a night. I may need your help tomorrow though, lol

    Thanks again for all the help so far though.

  9. #9
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    From what I understand about fork(), it creates an exact copy of the parent process; so can't you create a counter that's initialized to 8, then in the else if (pid == 0) block you decrement the counter and put the whole fork() & if statement block in a loop...? Seems pretty simple.
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  10. #10
    Registered User
    Join Date
    Feb 2010
    Posts
    25
    Quote Originally Posted by cpjust View Post
    From what I understand about fork(), it creates an exact copy of the parent process; so can't you create a counter that's initialized to 8, then in the else if (pid == 0) block you decrement the counter and put the whole fork() & if statement block in a loop...? Seems pretty simple.
    Nope. Tried it. Prints out at least 100 PIDS.

    Code:
    	pid_t pID = fork();
    	for(i = 8; i > 0; i++)
    	{
    		if(pID == 0)	//Child
    		{
    			//Code only executed by child process
    			//sIdentifier = "Child Process: ";
    			//globalVariable++;
    			//iStackVariable++;
    			cout << "Child pID" << getpid() <<endl;
    			fork();
    		}
    		else if(pID < 0)	//Failed to fork
    		{
    			cerr << "Failed to fork" << endl;
    			exit(1);
    			//Throw Exception
    		}
    		else	//Parent
    		{
    			//Code only used by parent process
    			//sIdentifier = "Parent Process: ";
    			cout << "Parent pID" << getpid() <<endl;
    			fork();
    		}
    I tried it with the fork() in the conditionals, out of it, you name it I tried it. I don't know what the hell it's doing.

  11. #11
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by CheckMyBrain View Post
    I have an assignment due that requires me to create 8 processes. 3 of the processes are supposed to have 2 children each.
    Wait a sec, if you have 3 processes that each have 2 child processes, that would give you 9 processes total. Something doesn't sound right with the requirements.

    Anyways, I don't think you need to create all 8 processes in one loop, do you?
    Couldn't you have the first loop create the parents, then another loop to create 2 children for each parent?
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  12. #12
    Registered User
    Join Date
    Feb 2010
    Posts
    25
    Quote Originally Posted by jeffcobb View Post
    if all you had to do is report proc IDs then you probably just need a single mutex-protected printPID(int PID) function that prints the process ID via cout, printf, whatever. Call as needed from within each forked process. As for controlling who has kids and who doesn't, a simple mutex-protected data structure/variable indicating the current logical process being spun (1-8) and inside the child proc a switch or just a check to see if it is process 2, 3, whatever and if so, call fork() again.

    This is off the top of my head whilst eating though...
    I don't know how to get the process ID number. getpid() isn't cooperating; neither is assigning it to an int. When I assign it to an int, it calls all the processes that are made. I don't know what to do! I just want to make an array of integers that holds process ID numbers.

  13. #13
    Registered User
    Join Date
    Feb 2010
    Posts
    25
    Quote Originally Posted by cpjust View Post
    Wait a sec, if you have 3 processes that each have 2 child processes, that would give you 9 processes total. Something doesn't sound right with the requirements.

    Anyways, I don't think you need to create all 8 processes in one loop, do you?
    Couldn't you have the first loop create the parents, then another loop to create 2 children for each parent?
    One only has one child. I don't know how to create processes and then keep track of them. All the methods seem to be static. It's not like pid.fork() it's just fork(). How do you keep track of that? Even when I put getpid() into an int, it'll contain all the processes, not just the recently created one.

  14. #14
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875
    Query: can *any* three respawn? or specific ones? your solution may be simpler than it is hard..
    C/C++ Environment: GNU CC/Emacs
    Make system: CMake
    Debuggers: Valgrind/GDB

  15. #15
    Registered User
    Join Date
    Feb 2010
    Posts
    25
    It's supposed to be like this:
    Code:
                            7
                     4-------
             2--------      8
    1--------        5
             |
             3-------6
    Honestly, I don't think it really matters who goes where, as long as I can get 8. I can figure out which ones belong to who once I have them all stored.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help needed on parallel processing using fork() in C
    By smithu.simi in forum C Programming
    Replies: 7
    Last Post: 03-27-2009, 07:15 AM
  2. Parallel processing with fork()
    By Mastiff in forum C Programming
    Replies: 7
    Last Post: 08-27-2008, 07:42 AM
  3. fork(), exit() - few questions!
    By s3t3c in forum C Programming
    Replies: 10
    Last Post: 11-30-2004, 06:58 AM
  4. Daemon programming: allocated memory vs. fork()
    By twisgabak in forum Linux Programming
    Replies: 2
    Last Post: 09-25-2003, 02:53 PM
  5. file writing crashes
    By test in forum C Programming
    Replies: 25
    Last Post: 08-13-2002, 08:44 AM