Click to See Complete Forum and Search --> : Basic fork()/processes question


dogn00dles
07-30-2002, 10:50 PM
Here is the code in question:

#include <iostream>
#include <sys/types.h>
#include <unistd.h>

int main()
{
pid_t child_pid;
cout<<"the main process is:"<<getpid();
child_pd = fork();
if(child_pid != 0){
cout<<"this is the parent process id"<<getpid();
cout<<"this is the child's"<<child_pid();
else
cout<<"this is the child process"<<getpid();
return 0;
}

So is prints the main process pid, forks it, and says: if the child pid is zero print both the child's and the parent's. So if it's running as child, that prints, because the child returns "0" (and the parent returns the child pid). But I have some questions. For one, is pid_t a data type? And when I compile it, it prints everything, that confused me. Does anyone know why this is? thanks,

-dogn00dles

The Kooman
07-30-2002, 11:52 PM
You're seeing all the messages because both the programs are running simultaneously. If you give a "wait()" in the parent to wait for the child to be over and then print your messages, then you'd see something "sensible" (not that its not sensible now) ;)!

BTW, I think there's a typo in your code - it should be "child_pid" when you're "cout"ing it and not "child_pid()", since there's no function called "child_pid()"!


/* I prefer to write in C (as against C++) ;) */
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
pid_t child_pid;
printf ("the main process is:%d\n", getpid());
if ((child_pid = fork()) != 0) {
printf("this is the parent process id:%d\n", getpid());
wait();
printf("child process is over now. This was the child's PID:%d\n", child_pid);
} else {
printf("this is the child process:%d\n", getpid());
}
return 0;
}


"man wait" for more on the "wait()" system call. Read up Richard Stevens for even more on fork()s and wait()s ;)

As for pid_t - its "typedef"ed to "__kernel_pid_t" in /usr/include/linux/types.h. "__kernel_pid_t" is "typedef"ed to "int" in /usr/include/asm/posix_types.h

HTH

dogn00dles
07-31-2002, 12:02 AM
Thanks, that finally makes sense now. From what I've read (I guess you could say I "know" C++, but haven't really delved into its more advanced features) C++ is pretty much C with classes (wasn't that its original name?). Is there a major reason to switch, or just personal preference? Thanks,
dogn00des

The Kooman
07-31-2002, 12:18 AM
Well, I did work on C++ for a while and what I found out was that debugging C++ code was hell. I was maintaining some huge legacy software with millions of lines of code. To make sense of anything we needed a class hierarchy tool which was a pain to find. Then, on top of that, you gotta admit that there are some, ummm, not so smart programmers in the industry. So things do get horribly obfuscated :mad:.

The switch back to C was because my new job required it. Debugging C code is much easier, even if its dirty ;)!

And last but not the least (and I know I can start a war here ;)), inspite of all the great things people say about OOP, my experience has shown that people rarely re-use code ... esp. classes!! People spend ages designing and writing classes with a lot of generic, unused stuff (member functions, etc) in it. But as soon as somebody new takes over the project, the same cycle starts all over again!!! You might argue that the same thing happens in C, but then, in C, I don't really see too many people putting in really generic things into a module just 'coz it should look like a "good" class!!! So there's less junk resulting in a smaller footprint.

I suppose you can make out - I'm not too great a fan of OOP ;). Just plain encapsulation is enough for most of my needs till date. Have never felt the need for inheritance. ... And "traditional" imperative languages do offer decent encapsulation!

*Phew*, I can rant :D!!!

Kinjana
08-01-2002, 02:31 AM
It prints both becuase the fork call creates a duplicate process.

The new process consists of a copy of the address space of the orignal process . this allows the parent to communicate easily with its child. BOTH continue execution at the instruction after the fork system call, with one difference. The return code for the fork call is zero for the child and the non zero process identifier of the child is returned to the parent.

Usually an execlp(...) call is used after a fork by one of the two process to replace that process'; memory space with a new program.



modifying your code slightly...

child = fork();

if (child == 0) { /*child process*/
execlp("/bin/ls","ls","NULL);


} else if ((child != 0) {

wait(NULL);
printf("child complete\n");

}

the major thing to recognize is that you initially get two different processes running a copy of the same progrtam. This is an excellent way for two processes to commicate and then go their seperate ways --- there is no requiremnet that the parent wait for the child to finish executing. They both continue.

Kinj --