5 Replies - 318 Views - Last Post: 11 February 2014 - 11:53 PM Rate Topic: -----

#1 IngeniousHax  Icon User is offline

  • |>|20-514<|{3|2

Reputation: 78
  • View blog
  • Posts: 1,358
  • Joined: 28-March 09

C fork() and processing

Posted 09 February 2014 - 09:38 PM

Hey everyone, I have a question regarding unix fork(). I am trying to take a 2 dimensional non-square array (m x n) and process it like a tree (not a traditional tree).

For example, given the following input:
x y 3 a b z
b k 1 s
l s 0
z g 1 h

It would output:
x-y
   a
   b-k
      l-s
   z-g
      h


Essentially the first two columns are parents, and the number of children come after the integer. I have no idea how to properly use fork, or how to get this to work. I have tried many things, but just end with wonky input, like long repetitions of parent 1, with some randomly indented letters.

So I was wondering if someone could point me in the right direction with this. Here is my code I currently have, it's a disaster.

Got some updated code that isn't AS ugly and works better.
for(int i = 0; i < rows; i++)
{
printf("%c", data[i][0]);
// Create process for parent_1
if((pid = fork()) == 0)
{
	for(int j = 2; data[i][j] != '\0'; j++)
	{

		if(data[i][j] > '0')				// At the integer, must be > 0
		{
			j += 1;							// increment j by one to bypass integer
			if((child_pid = fork()) == 0)	// Create a process for the child
			{
				int temp = i+1;
				while(temp < rows)
				{
					if(data[temp][0] == data[i][j])		// next line parents and current child of prev. parent
					{
						printf("\n\t%c-%c", data[temp][0], data[temp][1]);
						exit(child_pid);
					}
					temp++;
				}
				exit(child_pid);
			}
			else if(child_pid < 0)
			{
				printError("Error: Unable to fork", MEMORY_ERR);
			}
			else
			{
				printf("\n\t%c", data[i][j]);
				waitpid(child_pid, 0, 0);
			}
		}
	}
	exit(pid);
}
else if(pid < 0)
{
	printError("Error: Unable to fork", MEMORY_ERR);
}
else
{
	printf("-%c\n\t", data[i][1]);
	waitpid(pid, 0, 0);
}



Given the input:
A B 3 C D X
D Y 2 M E
M F 0
C P 1 K

--[ output should look like ]--
A-B
   C-P
      K
   D-Y
      M-F
        E
    X


I receive
A-B
A
A
	C-P	C
	C	X	D-Y
	D
	D
	M-F	M
	M
	-		M-F
	M	C-P
	C
	C	K	-



As for a set of pseudocode, to try and explain what I want it to do, should go something like this:
print first of parents
   fork on parent[0][1]
   if child
     fork on child
       iterate through remaining parents
       if child is also a parent
       print the partner
       search current children
       repeat



I think, I just don't understand the forking or how it works with iteration/recursion. I feel this would be a great recursive solution, if I could understand fork(). (have read man pages as well)

This post has been edited by IngeniousHax: 09 February 2014 - 11:36 PM


Is This A Good Question/Topic? 0
  • +

Replies To: C fork() and processing

#2 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3552
  • View blog
  • Posts: 11,009
  • Joined: 05-May 12

Re: C fork() and processing

Posted 09 February 2014 - 11:32 PM

Can you post the exact assignment text? It's unclear why you would even need to use fork().
Was This Post Helpful? 0
  • +
  • -

#3 GWatt  Icon User is offline

  • member icon

Reputation: 270
  • View blog
  • Posts: 3,068
  • Joined: 01-December 05

Re: C fork() and processing

Posted 09 February 2014 - 11:40 PM

I guess the first thing to do is understand how fork works. http://pubs.opengrou...tions/fork.html
The short version is that fork creates a new process that inherits file descriptors and memory from the parent. However, after fork is called the processes don't share memory. Any changes made to variables in one process are not seen in the other. There are other fiddly bits of fork, but I don't think those are relevant for your bit of code. In answer to your question about how forking interacts with iteration/recursion: it doesn't. Fork creates a new process and then parent and child continue execution after fork returns. If you forked from within a function call (recursive or not) both parent and child will complete the function normally, and then return back up the stack. Likewise, if you forked from within a loop both parent and child will finish the loop normally and go on to do whatever is after the loop.
The question I have is: Why are you using fork? It's not really necessary or helpful for what I understand you goal to be.

With regards to your code, I think you have everything properly thought out in the pseudo-code, but no where in your actual code do you check to see if the current child is also a parent of some other family.

[edit] revised to reflect updated original post.

This post has been edited by GWatt: 09 February 2014 - 11:42 PM

Was This Post Helpful? 0
  • +
  • -

#4 IngeniousHax  Icon User is offline

  • |>|20-514<|{3|2

Reputation: 78
  • View blog
  • Posts: 1,358
  • Joined: 28-March 09

Re: C fork() and processing

Posted 10 February 2014 - 01:08 AM

Yeah, it's required for the assignment, but I have made signifcant progress since my last update, which has taken about two steps in the reverse. But the assignment states that the eldest parent is listed first.
1. A parent MUST create a process for each of it's children
2. Wait until that parents children die
3. Check if the present name is getting married to another person
4. Print the present name and the present partners name as: <present>-<present_partner>

The files are given in the format
<parent_1> <parent_2> <n> <child_1>...<child_n>
.
.
.



I am pretty sure it should go something like this, in pseudocode
for i <- 0 to rowMax
   fork // parent
     for j <- 2 until '\0'
        if a[i][2] is > '0'
          fork // child
            check row[i][0] and row[i][1] for "partner" of child
               if partner exists
                  print child and present_partner
                  if a[i][2] is > '0'
                     print child
                  else
                     exit child_pid
               else
                 i += 1
             while i != rowMax
             exit child_pid
          exit pid
     print a[i][0]-a[i][1]


Was This Post Helpful? 0
  • +
  • -

#5 vividexstance  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 656
  • View blog
  • Posts: 2,247
  • Joined: 31-December 10

Re: C fork() and processing

Posted 10 February 2014 - 11:29 AM

You shouldn't call exit() from a child process. The exit() function ends up calling the _exit() function among other things, like cleaning up, so from your child processes, just use the _exit() function.
Was This Post Helpful? 0
  • +
  • -

#6 IngeniousHax  Icon User is offline

  • |>|20-514<|{3|2

Reputation: 78
  • View blog
  • Posts: 1,358
  • Joined: 28-March 09

Re: C fork() and processing

Posted 11 February 2014 - 11:53 PM

Alright, I have been working on this feverishly, and I have made some decent progress. Where is it I am going worng with it though, I do not know. Here is the output I receive:
A-B
	C-P
		D-Y
			X
	M-F
		E
	K
			K
				M-F
					E
	K
						K



And the output I should be receiving:
A-B
   C-P
       K
   D-Y
       M-F
       E
   X



And here is the code I have... It's terrible looking, but currently just getting it to work seems ot be the main concern.
printf("%c-%c\n", data[0][0], data[0][1]);
	for(P_index = 0; P_index < P_rows; P_index++)
	{
		/* Fork on parent */
		if((pid = fork()) == 0)
		{
			if(isdigit(data[P_index][C_count]) && (int)data[P_index][C_count] > 0)
			{
					for(C_index = 3; data[P_index][C_index] != '\0'; C_index++)
					{
						printf("\t");
						if((child_ppid = fork()) == 0)
						{
							tempIndex = P_index + 1;
							while(tempIndex < P_rows)
							{
								if(data[tempIndex][0] == data[P_index][C_index])
								{
									printf("%c-%c\n", data[P_index][C_index],data[tempIndex][1]);
									if(isdigit(data[tempIndex][C_count]) && (int)data[tempIndex][C_count] > 0)
									{
										if((child_pid = fork()) == 0)
										{
											C_index += 1;
											for(C_index; data[tempIndex][C_index] != '\0'; C_index++)
											{
												printf("\t%c\n", data[tempIndex][C_index]);
											}
										}
										else if(child_pid < 0)
										{
											perror("Unable to fork");
										}
										else
										{
											waitpid(child_pid, NULL, 0);
											_exit(0);
										}

									}
									_exit(0);
								}
								tempIndex++;
							}
							printf("%c\n", data[P_index][C_index]);
						}
						else if(child_pid < 0)
						{
							perror("Unable to fork");
						}
						else
						{
							waitpid(child_ppid, NULL, 0);
							//_exit(0);
						}
					}
			}
			else
			{
				//printf("%c-%c\n", data[P_index][0], data[P_index][1]);
				_exit(0);
			}
		}
		else if(pid < 0)
		{
			perror("Unable to fork");
		}
		else
		{
			waitpid(pid, NULL, 0);
			_exit(0);
		}
	}



A sample input from a file has the following format:
A B 3 C D X
D Y 2 M E
M F 0
C P 1 K



Where am I getting the extraneous output of - from, and how can I fix this so I don't get out of order printing like I am? Any help is greatly appreciated!

EDIT: Got some better looking output, but still not quite right...
printf("%c-%c\n", data[0][0], data[0][1]);
	for(P_index = 0; P_index < P_rows; P_index++)
	{
		/* Fork on parent */
		if((pid = fork()) == 0)
		{
			if(isdigit(data[P_index][C_count]) && (int)data[P_index][C_count] > 0)
			{
					for(C_index = 3; data[P_index][C_index] != '\0'; C_index++)
					{
						printf("\t");
						if((child_ppid = fork()) == 0)
						{
							//tempIndex = P_index + 1;
							while(tempIndex < P_rows)
							{
								if(data[tempIndex][0] == data[P_index][C_index])
								{
									printf("%c-%c\n", data[P_index][C_index],data[tempIndex][1]);
									if(isdigit(data[tempIndex][C_count]) && (int)data[tempIndex][C_count] > 0)
									{
										if((child_pid = fork()) == 0)
										{
											for(C_index; data[tempIndex][C_index] != '\0'; C_index++)
											{
												printf("\t%c\n", data[tempIndex][C_index]);
											}
										}
										else if(child_pid < 0)
										{
											perror("Unable to fork");
										}
										else
										{
											waitpid(child_pid, NULL, 0);
											_exit(0);
										}
									}
									_exit(0);
								}
								tempIndex++;
							}
							printf("%c\n", data[P_index][C_index]);
							_exit(0);
						}
						else if(child_pid < 0)
						{
							perror("Unable to fork");
						}
						else
						{
							waitpid(child_ppid, NULL, 0);
							//_exit(0);
						}
					}
					_exit(0);
			}
			else
			{
				//printf("%c-%c\n", data[P_index][0], data[P_index][1]);
				_exit(0);
			}
		}
		else if(pid < 0)
		{
			perror("Unable to fork");
		}
		else
		{
			waitpid(pid, NULL, 0);
			_exit(0);
		}
	}



NEW OUTPUT
A-B
	C-P
	K
		D-Y
	E
			X


This post has been edited by IngeniousHax: 12 February 2014 - 12:48 AM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1