<br><br><div class="gmail_quote">On Sat, Jan 19, 2013 at 5:49 AM,  <span dir="ltr">&lt;<a href="mailto:Valdis.Kletnieks@vt.edu" target="_blank">Valdis.Kletnieks@vt.edu</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On Fri, 18 Jan 2013 19:59:38 +0530, Niroj Pokhrel said:<br>
<br>
&gt; I have been trying to create a process using vfork(). And both of the child<br>
&gt; and the parent process execute it in the same address space. So, if I<br>
&gt; execute exit(0) in the child process, it should throw some error right.<br>
<br>
</div>Why do you think it should throw an error?<br>
<div class="im"><br>
&gt; Since the execution is happening in child process first and if I release<br>
&gt; all the resources by using exit(0) in the child process then parent should<br>
&gt; be deprived of the resources and should throw some errors right ??<br>
<br>
</div>No, because those resources that were shared across a fork() or vfork() were in<br>
general *multiple references* to the same resource.<br>
<br></blockquote><div><br></div><div>Yes, correct, Valdis is right.   Normally, when u free resources (which is what &quot;exit()&quot; will do), u must also remember to check something call &quot;reference count&quot;.   </div>
<div><br></div><div>Basic malloc() and free() memory management internal data structure also comes with other info like size (which is 4 bytes BEHIND the first byte where the pointer points to, and other info).   More info:</div>
<div><br></div><div><a href="http://stackoverflow.com/questions/1957099/how-do-free-and-malloc-work-in-c">http://stackoverflow.com/questions/1957099/how-do-free-and-malloc-work-in-c</a></div><div><br></div><div>but what is lacking is reference counting.   But this feature is available in Java and C++ libraries for memory allocation.</div>
<div><br></div><div>Concept discussed here:</div><div><br></div><div><a href="http://stoneship.org/essays/c-reference-counting-and-you/">http://stoneship.org/essays/c-reference-counting-and-you/</a></div><div><br></div><div>
Interesting....</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
As an example - imagine a flagpole.  You grab it with your hand, you&#39;re<br>
now holding it.  You invite your friend to come over and grab it with<br>
his hand - now he&#39;s holding it too.<br>
<br>
But either one of you can let go of the flagpole - and the other one is<br>
still holding the flagpole until *they* let go.  And the order you let<br>
go doesn&#39;t matter in this case - which is important because your example<br>
code has a race condition....<br>
<br>
Note that there are other cases where the order people let go *does* matter.<br>
This is when you start having to worry about &quot;locking order&quot; and things like<br>
that.<br>
<div class="im"><br>
&gt; In the following code, however the process ran fine even though I have<br>
&gt; exit(0) in the child process ........<br>
<br>
&gt; #include&lt;stdio.h&gt;<br>
&gt; #include&lt;stdlib.h&gt;<br>
&gt; #include&lt;sys/types.h&gt;<br>
&gt; #include&lt;unistd.h&gt;<br>
&gt; int main()<br>
&gt; {<br>
&gt;     int val,i=0;<br>
&gt;     val=vfork();<br>
&gt;     if(val==0)<br>
&gt;     {<br>
&gt;         printf(&quot;\nI am a child process.\n&quot;);<br>
<br>
</div>Note that printf() gets interesting due to stdio buffering.  You probably<br>
want to call setbuf() and guarantee line-buffering of the output if you&#39;re<br>
playing these sorts of games - the buffering can totally mask a real race<br>
condition or other bug.<br>
<div class="im"><br>
&gt;         printf(&quot; %d &quot;,i++);<br>
&gt;         exit(0);<br>
&gt;     }<br>
&gt;     else<br>
&gt;     {<br>
<br>
</div>/* race condition here - may want wait() or waitpid() to synchronize? */<br>
<div class="im"><br>
&gt;         printf(&quot;\nI am a parent process.\n&quot;);<br>
&gt;         printf(&quot; %d &quot;,i);<br>
&gt;     }<br>
&gt;     return 0;<br>
&gt; }<br>
&gt; // The program is running fine .....<br>
&gt; But as I have read it should throw some error right ?? I don&#39;t know what I<br>
&gt; am missing . Please point out the point I&#39;m missing. Thanking you in<br>
&gt; advance.<br>
<br>
</div>You&#39;re also missing the fact that after the vfork(), there&#39;s no real<br>
guarantee of which will run first - which means that the parent can race<br>
and output the &#39;printf(&quot;%d&quot;,i)&quot; *before* the child process gets a chance<br>
to do the i++.<br>
<br></blockquote><div><br></div><div>I don&#39;t think there is any issue here (racing, or child calling exit before parent called exit()).   Read the man-page:</div><div><br></div><div><div>       vfork()  differs from fork(2) in that the parent is suspended until the</div>
<div>       child terminates (either normally, by calling _exit(2), or  abnormally,</div><div>       after  delivery  of  a  fatal signal), or it makes a call to execve(2).</div><div>       Until that point, the child shares all memory with its parent,  includ‐</div>
<div>       ing  the stack.  The child must not return from the current function or</div><div>       call exit(3), but may call _exit(2).</div></div><div><br></div><div><br></div><div>So:</div><div><br></div><div>1.   if parent is suspended, it also means no contention issue, child can use the &quot;i++&quot;, which is single-copy in memory, and parent is not even touching it.</div>
<div><br></div><div>2.   It is clearly documented above - the vfork()&#39;s child CAN exit() before the parent calling exit().</div><div><br></div><div>3.   More important is to understand the the use of vfork() - u don&#39;t to create a duplicate memory page table because u want to call execve() immediately, which will overwrite everything in memory with the new binary inside execve() command.</div>
<div><br></div><div>Hope I got it right?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
(Aside - for a while, there was a patch in place that ensured that the<br>
child would run first, on the theory that the child would often do something<br>
short that the parent was waiting on, so scheduling parent-first would just<br>
result in the parent running, blocking to wait, and we end up running the<br>
child anyhow before the parent could continue.  It broke an *amazing* amount<br>
of stuff in userspace because often the child would exit() before the parent was<br>
ready to deal with the child process&#39;s termination. Usual failure mode was<br>
the parent would set a SIGCHLD handler, and wait for the signal which never<br>
happened because the SIGCHLD actually fired *before* the handler was set up).<br>
<br>
(And on non-cache-coherent systems, it&#39;s even possible that the i++ happens<br>
on a different CPU first, and the CPU running the parent process never becomes<br>
aware of it.  See &#39;Documentation/memory-barriers.txt&#39; in the Linux source<br>
for more info on how this works for data inside the kernel.  This example<br>
is out in userspace, so other techniques are required instead to do cross-CPU<br>
synchronization.<br>
<br>_______________________________________________<br>
Kernelnewbies mailing list<br>
<a href="mailto:Kernelnewbies@kernelnewbies.org">Kernelnewbies@kernelnewbies.org</a><br>
<a href="http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies" target="_blank">http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies</a><br>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br>Regards,<br>Peter Teoh