ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hi all.
I know that there have been many posts on forks, but none of them answer my question exactly. I know that a fork starts another process, but where exactly does the new process start running its code? After the fork? At the beggining of the program?
What I expected the prog to do was produce: "abc...mmnnooppqq..." but instead I got "abcde...xyzabcde...xzy". Does this mean that the process gets started from the beggining of the code or is there some other reason for this behaviour.
what was happenning was, in the time it takes for the fork to copy its data to form the second process(fork is not very fast) the first process had finished. as for why it started at a again im not sure but i think its a related problem.
as the man page says, the new process starts at the return from the fork() and the value returned can be used to determine if you are in the child or not.
Thanks kev for the reply, but still no luck. The only difference is that the output takes really long to display and it always displays the output all at once ie "abc..." for the parent process and then "abc..." for the child process a while later.
I'm running Redhat 8.0 and compilling and running the programs in the terminal. Could this have any affect? I'm currently in windows so I can't test it now. Can someone at least tell me if the above program works on there system. Thank you again.
it works on mine, your flush isnt working properly. replace cout<<i<<flush; with cerr<<i; that should work as cerr is not buffered. if it doesnt then im really confused, try it on someone elses machine.
Hey, you had me intrigued for a while, too. What I think is happening is this:
cout is buffered, so somewhere there is a buffer. Now, looping until you get to fork is not enough to flush the buffer, so the buffer will contain
"abcdefghijklm"
Now, when you fork, this buffer will be forked, too. So when both loops proceeds in either process, they will both append to their own copy of the above buffer, and will thus produce identical output when the buffer is flushed at process end. The timing or speed of fork has nothing to do with it; it's all a matter of buffering. As kev82 writes, using cerr instead of cout will probably elminate this problem -- flushing the buffer before fork will (tested).
Here's my version of the testing program:
#include <unistd.h>
#include <iostream>
using namespace std;
int main(int argc, char* argv[]) {
cout << ((argc>1)?"Flush before fork":"Not flush before fork") << endl;
for (char i = 'a'; i <= 'z'; i++) {
cout << i;
if ('m' == i) {
if (argc>1)
cout << flush;
fork();
}
}
cout << endl;
sleep(1);
return 0;
}
And a testrun:
esben ~/c++/diverse $ ./fork
Not flush before fork
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
esben ~/c++/diverse $ ./fork 5
Flush before fork
abcdefghijklmnopqrstuvwxyz
nopqrstuvwxyz
esben ~/c++/diverse $
esben is correct about fork copying the buffer, that explains why a,b etc appear twice, i hadnt considered that. you still have the problem that your flush doesnt work though, so you should try using cerr to see what happens.
Wow, not bad at all. Thank you all. It works almost perfectly. Sorry Kev I misread your first post and forgot to flush Here is the full code
using namespace std;
int main()
{
int pid;
for(char i='a';i<'z';i++)
{
cout<<i<<flush;
if(i=='m')
{
pid=fork();
if(pid!=0)
{
sleep(7);
}
}
sleep(1);
}
if(pid!=0)
{
cout<<"The id of the child process is "<<getpid()<<endl;
}
else
{
cout<<"The id of the parent process is "<<getpid()<<endl;
}
if(pid!=0)
{
cout<<"Press a key to exit"<<endl;
getchar();
}
return 0;
A few more qeustions if you guys have any patience left .
1) I want the program to print "abc...mmnnoo.....zz" so I have a problem with timing. Any suggestions?
2) When both processes have finished printing the alphabet , the parent process must wait for the child process to finish, then print its ID and then quit. I must use the wait() command for this,right? I can't "man wait", am I missing files or are there no man pages for wait()
3) When did gcc start using namespaces and is there a way to disable them?
1) my program in post 2 does exactly that.
2) there are man pages for wait() and waitpid(), you should have them installed, you can get them from your local kernel.org mirror.
3) probably since they became a part of the C++ standard, but possibly before. no you cant disable them, why would you want to?
<edit> please use code tags, it makes is ALOT easier to read your code
Originally posted by Avatar33
A few more qeustions if you guys have any patience left .
1) I want the program to print "abc...mmnnoo.....zz" so I have a problem with timing. Any suggestions?
2) When both processes have finished printing the alphabet , the parent process must wait for the child process to finish, then print its ID and then quit. I must use the wait() command for this,right? I can't "man wait", am I missing files or are there no man pages for wait()
3) When did gcc start using namespaces and is there a way to disable them? [/B]
1) Well, you could use a pipe to synchronize the two, if you want. Another way is to create a socketpair. See main 2 pipe and man socketpipe. But what's the purpose? It seems to be a very complicated way to print a few letters
2) I can cetainly man wait. There's plenty of internet sites carriying the full linux man pages, so google is another way. Using wait or waitpid is the way to wait for the child to finish, yes.
3) Dunno about disabling, but "info gcc" (or man gcc if you prefer) will certainly answer that one. But remember: namespaces are there for a very good reason. Why disable them?
Hi,
[1] First of all please do not use gcc for C++ programs. Although it compiles them still you should use g++ that is a wrapper on gcc for CPP programs.
as far as the namespace thing is concerned, if you use iostream.h (header file) instead of iostream (it is a wrapper on former and is called a package not a header), then you would not need writing namespace.
[2] as there are two separate processes, and there turn is decided by the os schedular, please do not take the risk of assuming the output sequence.
Originally posted by dharmender_rai Hi,
if you use iostream.h (header file) instead of iostream (it is a wrapper on former and is called a package not a header), then you would not need writing namespace.
you should not use iostream.h, it is limited to char based streams and it has a different interface than iostream. if you want to get rid of namespaces just put 'using namespace std;' at the start of your program and you can forget about them.
I think i am missing the point of this thread; why do you expect the output of the two processes to be synchronised when you do not use any synchronisation primitives (mutexes, semaphores) ?
The output of the program in the original question is perfectly allright. On a uniprocessor system with a non-preemptive kernel (linux 2.4 i presume) context switches between parent and child may occur when you call a system (s. manpages, section 2) function. Then again, it may not consider giving the cpu to the child process before the parent terminates.
The flush method suggested is not guaranteed to work. A C++ library is allowed to pass a buffer on to an underlying userspace buffering solution, like C's stdio, so the kernel still wont know about the new output, and no system call, and therefore no context switch will take place.
Thanks for all the replies, you have all been a great help.
1) The reason that I want to disable namespaces is that gcc on the universities computers does not use them and it will make it easier for me to have working code on the universities computers if I don't use namespaces.
2) The point of the program is to help me learn.
3)
Quote:
as there are two separate processes, and there turn is decided by the os schedular, please do not take the risk of assuming the output sequence.
I agree with this statement so I will use pipes to synchronize my programs.
It seems I've solved all my problems for now, thanks to you guys.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.