[C] Read different files with different processes [Resolved]

Started by Apidcloud, November 14, 2012, 08:09:48 pm

Previous topic - Next topic

Apidcloud

Hey there, I got homework (related to C), which asks to read different .txt files with different processes.
At the end of each child process, we must print .txt file's characters number

I tried this approach:
#include <stdio.h>
#include <stdlib.h>
void main(int argc, char* argv[])
{
int i, j, FILE *fp;
char c;
for(j=1;j<argc;j++)
{
if (fork() == 0) // child process
{
if ((fp = fopen(argv[j],"r")) == NULL)
{
printf("Error when trying to open file");
exit(-1);
}
i = 0;
while((c=fgetc(fp)) != EOF) // tried while(!eof(fp)) but it didn't work
{ i++; }
printf("The characters number from %d text file is %d",j,i);
fclose(fp);
// even tried kill(getpid()) after closing the file, but it also didn't work
}
}
exit(0);
}


As predicted, if we run the program using 2 files as parameters, we get 4 prints..
The thing is, child processes aren't stopping, which is why I tried to kill each one of them after closing the file, but it didn't work either.

What am I missing here? I know exactly why it is wrong, but I don't know how to make each process read only 1 file.

Thanks,
Apidcloud

Answer:
Code: by Blizzard
#include <stdio.h>
#include <stdlib.h>
void main(int argc, char* argv[])
{
int i, j, FILE *fp;
char c;
for(j=1;j<argc;j++)
{
if (fork() == 0) // child process
{
if ((fp = fopen(argv[j],"r")) == NULL)
{
printf("Error when trying to open file");
exit(-1);
}
fseek(fp, 0, SEEK_END); // this and the line below have better performance, and are also cleaner than a loop
i = ftell(fp);
printf("The characters number from %d text file is %d",j,i);
fclose(fp);
exit(0); // The reason why it wasn't working normally
}
}
exit(0);
}
Instead of wanting to be somebody else, rather become somebody else



"I will treasure the knowledge like a squirrel treasures acorns."


Gibbo Glast 2D Engine - The sky is no longer a limit

Blizzard

That's weird. fork() should spawn a child process which automatically exits when you exit the parent process.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Apidcloud

Are you saying that theoretically the code should work?
when i first thought about it, i wondered if, in fact, the second iteration of the loop would be run by first child process..when running the program, i got 4 prints instead of 2, which means something is wrong  :wacko:
Instead of wanting to be somebody else, rather become somebody else



"I will treasure the knowledge like a squirrel treasures acorns."


Gibbo Glast 2D Engine - The sky is no longer a limit

Blizzard

November 15, 2012, 11:04:59 am #3 Last Edit: November 15, 2012, 11:06:57 am by Blizzard
Yeah, that's definitely unusual. There's also a thing which you can use to make the code cleaner/faster.

	// after opening the file
fseek(fp, 0, SEEK_END);
i = ftell(fp);
// now printing stuff


What do your 4 prints say?
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Apidcloud

Thanks for pointing a cleaner/faster way to count files characters.

I keep getting 4 prints:
The characters number from 2 text file is 18
The characters number from 1 text file is 48
The characters number from 2 text file is 18
The characters number from 1 text file is 48





Instead of wanting to be somebody else, rather become somebody else



"I will treasure the knowledge like a squirrel treasures acorns."


Gibbo Glast 2D Engine - The sky is no longer a limit

Blizzard

Print out the PID's as well. Let's see what happens.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Apidcloud

prints:
pid<21654> Number of characters from file 2 -> 18
pid<21653> Number of characters from file 1 -> 48
pid<21653> Number of characters from file 1 -> 48
pid<21655> Number of characters from file 2 -> 18


I don't understand why it prints 4 times. I would understand 3 prints, but not 4..

Edit: I think I need to kill each child process using exit or kill
Instead of wanting to be somebody else, rather become somebody else



"I will treasure the knowledge like a squirrel treasures acorns."


Gibbo Glast 2D Engine - The sky is no longer a limit

Blizzard

Likely. Your prints indicate that child process 1 might be spawning an own child process. Try this:

#include <stdio.h>
#include <stdlib.h>
void main(int argc, char* argv[])
{
int i, j, FILE *fp;
char c;
for(j=1;j<argc;j++)
{
if (fork() == 0) // child process
{
if ((fp = fopen(argv[j],"r")) == NULL)
{
printf("Error when trying to open file");
exit(-1);
}
fseek(fp, 0, SEEK_END);
i = ftell(fp);
printf("The characters number from %d text file is %d",j,i);
fclose(fp);
exit(0);
}
}
exit(0);
}

Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Apidcloud

Yes it works perfectly, thanks

The thing is, even if the first child process creates a child process on its own, the output would be 3 prints instead of 4 right(theoretically) ?

I can't think of a reason to have 4 prints in my output...

Thanks again  :)
Instead of wanting to be somebody else, rather become somebody else



"I will treasure the knowledge like a squirrel treasures acorns."


Gibbo Glast 2D Engine - The sky is no longer a limit

Blizzard

Actually it may make sense after all. The first child process not only spawns another child, but also executes its own code twice (first run and after spawning its own child). Not that it makes much sense, but it would explain why the prints of the first file would be attributed to the same PID.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Apidcloud

November 15, 2012, 02:44:34 pm #10 Last Edit: November 15, 2012, 02:46:40 pm by Apidcloud
The part of executing the code twice doesn't make much sense since it would normally increment the iteration and "would" normally exit after creating its own child but it doesn't seem that way ehehe

Thanks for helping, Blizzard  :shy:
Spoiler: ShowHide



Edit:
Should I edit first post and add the answer?

Grateful  :)
Instead of wanting to be somebody else, rather become somebody else



"I will treasure the knowledge like a squirrel treasures acorns."


Gibbo Glast 2D Engine - The sky is no longer a limit

Blizzard

Quote from: Apidcloud on November 15, 2012, 02:44:34 pm
The part of executing the code twice doesn't make much sense since it would normally increment the iteration and "would" normally exit after creating its own child but it doesn't seem that way ehehe


I think it fell through in the second iteration of fork() == 0 or something like that.

Quote from: Apidcloud on November 15, 2012, 02:44:34 pm
Should I edit first post and add the answer?


Sure, why not.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Apidcloud

*Adds the answer to the main post*

I tried to use spoiler to contain the code, but it doesn't work well  :P
Instead of wanting to be somebody else, rather become somebody else



"I will treasure the knowledge like a squirrel treasures acorns."


Gibbo Glast 2D Engine - The sky is no longer a limit