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.
Assuming that both processes allow the flow to continue, those statements would be executed in both. Either process could, of course, exit, return, or call exec() prior to flowing out of the "if () { } else { }" construct.
Does the while(1) call belong to child or parent process ?
Both. The child process starts as a complete copy of the parent process, with the only difference being the return value from the fork() call. And to answer the unasked question, yes, if the child process does nothing that breaks that loop, the code you posted would turn into a fork bomb.
Both. The child process starts as a complete copy of the parent process, with the only difference being the return value from the fork() call.
From the book I read, it states that the code after fork() call is duplicated. The while(1) is placed before the fork call. So will it be duplicated? Can you give a pictorial illustration.
Thanks.
From the book I read, it states that the code after fork() call is duplicated. The while(1) is placed before the fork call. So will it be duplicated? Can you give a pictorial illustration.
Thanks.
I can't give you a picture illustration, but I'll try to explain.
First, back to some earlier comments about a fork() bomb. Well, I don't know if that's a term, but it applies. This code will fork() forever.
The wait() does nothing but wait(), it doesn't make things much better.
Ultimately this will fail when you reach system limits for processes.
Now back to your original questions Hitx11,
The function fork() creates an entire copy of the process which calls it, at the time the call occurs.
So say you have a bubble (your loop) and the code is spinning around that loop repeatedly.
You hit that fork() statement and right at that moment you have two completely identical bubbles, except they have different process numbers, "process ID values".
Right after the fork() call, they are different, but not by much:
They have different process ID numbers (PID)
The parent, retains the process ID number it has. It receives a return value from fork() which tells it the PID of the child process it just created
The parent also is linked to that child process, it will receive signals from the child, but this is only noticeable if you write some code to "look" for signals from that child process.
The child is also linked to the parent and it will send signals to the parent process. Signals are sent regardless of whether or not there is code. For instance if the child process exits, it will send a terminate signal to the parent; regardless whether the parent is actively looking for that signal. It will be sent, it will be received, but it may not be viewed. And that's all OK.
If the parent exits, all the children it created must go, and they will, and these are technical explanations of how System V works.
Back to when things return from fork():
There's a missing return case in that code example, fork() can fail and return -1, therefore the parent does not create a child. That's very rare, but it is a possibility.
As stated above, if you get a positive value in return from fork(), you are still the parent, and you've been given the PID of the child process you just created. Moving forwards, your exact copies of each other will now proceed to be different because they'll do different things and their databases of who they are, who their parents and children are, will be different. Meanwhile given that very simple code, they will be very similar in appearance.
When you receive a zero value in return from fork(), then you are the newly created child. You are very much an exact copy of the parent process which created you, with the exception of your PID number, the parent PID which created you, and the memory you occupy in RAM as a process. You are now a fully independent process and can fork() your own children if you wish, or not. You are free to copy whatever the parent who made you is doing, but the background database of who you are, your PID, your location in memory, your stack, your instruction pointer, your time slot to run in the system scheduler, those are all your own. Your only relations to your parent are that when you terminate, with or without failure, you will send them a signal. And they can either listen to it or not.
Bear in mind something that you may have not thought about:
When you start a new command line prompt in Linux - you have used fork().
When you write a program, and then run it on the command line, you have used fork() - the parent for your program which you ran from the command line IS the PID of the command line. You can check this.
Basically EVERY process in Linux is begat from another one. When Linux starts up, it creates a process and that forks other ones, leading to a large collection of processes in the system. Many of them continue forever, until shutdown That's all OK, it is by design.
That code use of fork(), while somewhat demonstrative, (a) is possibly confusing (b) will consume resources and memory and assigned process ID numbers until the system limits stop it, or RAM is exceeded and a system fault occurs (c) it is a pointless exercise because it really does nothing.
I'm sure there are a variety of other reasons for using fork(). I personally used it to create child processes from a master process, which I called a daemon process. The daemon's only purpose was to create the child processes and monitor them. If they died, the daemon would clean up after them, if needed, and then restart them. This was intended to be a system that was headless (embedded) and stayed up as much as possible. In theory, nothing's supposed to die or crash! But we live in a real world, I still make mistakes, made about 5 typing this paragraph, but I'm a fast typist and me hitting backspace rapidly is just common for me.
So I will point you to a number of blogs I've written about architecture which uses fork(), select(), exec(), pipes, and signals() to create children, monitor them, and establish a communications method between them.
It is not the end all-be all of programming, it's just something I'd done for a system and continue to practice because it works for me.
My point here is fork() is #1 a natural thing in the system that is used all the time even if you don't know about it, for instance when you launch a program by way of running it. Meanwhile you can use it with intent within your program, however my argument is besides "for fun" like is shown there, you are best to use it for it's intended purpose. To create another process which you intend to do something with, but maintain the link to your parent, for some reason.
Those blogs show:
- Making the daemon
- Forking the children, and giving them a communications means
- Monitoring the children, and contending with it when they fail
That's the biggest reason for using fork() or a different way to make other processes, making threads (those are similar but different, they are more tightly coupled together than separate processes), you need to know who each other are in the programming domain, so that you can communicate. There are many ways to communicate, however things like shared memory, process signals, pipes - they are more helpful when you have direct knowledge of who your process peer is. Yes, you can learn who a process peer is by looking into the /proc tree, or using other methods like storing information in files, but it is far faster and with greater benefits if you create a child of yourself, things like signals are automatically built in for that case Easier to use them.
The blogs, you may choose to read versus not. Enjoy! And yes they're very old ... so am I
4. The child is also linked to the parent and it will send signals to the parent process. Signals are sent regardless of whether or not there is code. For instance if the child process exits, it will send a terminate signal to the parent; regardless whether the parent is actively looking for that signal. It will be sent, it will be received, but it may not be viewed. And that's all OK.
Ouch! It sends SIGCHLD. A terminate signal (SIGTERM) would tell the parent to terminate (gracefully).
Quote:
5. If the parent exits, all the children it created must go, and they will, and these are technical explanations of how System V works.
Not at all. The orphaned children are adopted by the init process (PID 1). If an interactive shell (bash, specifically) terminates because it received a hangup signal (SIGHUP), it will resend that signal to all jobs, but it's up to each child process to decide what to do with that signal. For an interactive login bash shell, there is also a huponexit to send that SIGHUP when it exits for any reason, but that option is not set by default. And again, a child process can handle that signal in any way it wants.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.