Symbian3/SDK/Source/GUID-545DA961-217E-49CA-A90E-7A41E2C03A99.dita
changeset 7 51a74ef9ed63
parent 0 89d6a7a84779
equal deleted inserted replaced
6:43e37759235e 7:51a74ef9ed63
       
     1 <?xml version="1.0" encoding="utf-8"?>
       
     2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
       
     3 <!-- This component and the accompanying materials are made available under the terms of the License 
       
     4 "Eclipse Public License v1.0" which accompanies this distribution, 
       
     5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
       
     6 <!-- Initial Contributors:
       
     7     Nokia Corporation - initial contribution.
       
     8 Contributors: 
       
     9 -->
       
    10 <!DOCTYPE concept
       
    11   PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
       
    12 <concept id="GUID-545DA961-217E-49CA-A90E-7A41E2C03A99" xml:lang="en"><title>Forking
       
    13 without <codeph>exec()</codeph></title><shortdesc>A Unix-like system may create the child process using <codeph>fork()</codeph>,
       
    14 which then does not make a subsequent <codeph>exec()</codeph> call. The result
       
    15 of this is that the parent and child processes run the same executable. The
       
    16 child may communicate with the parent using pipes. One example of a system
       
    17 which does this is the email software program Exim (www.exim.org). In addition
       
    18 to forking without <codeph>exec()</codeph>, it can also <codeph>re-exec()</codeph> itself
       
    19 to regain dropped root privileges.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    20 <p>The issues that such systems encounter when porting to P.I.P.S. fall into
       
    21 two categories: <ul>
       
    22 <li><p><b>Little or no state data passed to child</b></p></li>
       
    23 <li><p><b>A lot of data passed to child</b></p></li>
       
    24 </ul></p>
       
    25 <section><title>Little or no state data passed to child</title><p>The first
       
    26 issue is where there is a little/no data passed to the child process on the <codeph>fork()</codeph> operation.
       
    27 Many examples of this exist in pre/post forking of listening sockets in TCP
       
    28 server applications, for example, in the MPM pre-fork module of the Apache
       
    29 server. More details are available at <xref href="http://httpd.apache.org/docs/2.2/mod/prefork.html" scope="external">http://httpd.apache.org/docs/2.2/mod/prefork.html</xref>. </p><p>This
       
    30 can be resolved by using the <xref href="GUID-E7C4DE71-BC5B-34AE-ACB3-C34A0DB1FC16.dita"><apiname>posix_spawn()</apiname></xref> operation, and
       
    31 passing any data using the <codeph>argv</codeph> parameters or environment
       
    32 variables. For more information about the <codeph>posix_spawn()</codeph> operation,
       
    33 see <xref href="http://www.opengroup.org/" scope="external">http://www.opengroup.org/</xref>.
       
    34 Note that some <codeph>argv</codeph> parameters must be used to distinguish
       
    35 the behaviour of the parent process from the subsequent behaviour of the child
       
    36 when the <codeph>main()</codeph> function is called; the behaviour of the
       
    37 child cannot be identical to the parent.  </p><p>The subsequent sections provide
       
    38 the following information: <ul>
       
    39 <li><p><b>Parent process forking example</b></p></li>
       
    40 <li><p><b>P.I.P.S. equivalent</b></p></li>
       
    41 </ul></p></section>
       
    42 <section><title>Parent process forking example</title><codeblock xml:space="preserve">#include &lt;stdio.h&gt;
       
    43 #include &lt;stdlib.h&gt;
       
    44 #include &lt;sys/types.h&gt;
       
    45 #include &lt;sys/wait.h&gt;
       
    46 #include &lt;unistd.h&gt;
       
    47 
       
    48 #define NUM_OF_PROCS 5
       
    49 
       
    50 int main(int argc, char *argv[])
       
    51 {
       
    52   pid_t Processpid[NUM_OF_PROCS];
       
    53      
       
    54   int I;
       
    55   
       
    56   for(I=1;i&lt;NUM_OF_PROCS;i++)
       
    57   {
       
    58      Processpid[i] = fork();
       
    59     
       
    60      if(Processpid[i] == 0)
       
    61      {
       
    62         printf("\r\n Child Process Inst[%d] running ***\r\n",I);
       
    63 
       
    64         //Terminate child process.5
       
    65         exit(0);
       
    66      }
       
    67      else
       
    68      {
       
    69         //Wait for the child process to terminate before forking the next one.
       
    70         waitpid(Processpid[i],NULL,0);
       
    71      
       
    72         printf("\r\n*** Child int[%d] process finished ***\r\n",I);
       
    73      }
       
    74   }
       
    75    
       
    76   return EXIT_SUCCESS;
       
    77 }
       
    78 </codeblock><p/></section>
       
    79 <section><title>P.I.P.S. equivalent</title><codeblock xml:space="preserve">#include &lt;stdio.h&gt;
       
    80 #include &lt;stdlib.h&gt;
       
    81 #include &lt;strings.h&gt;
       
    82 #include &lt;spawn.h&gt;
       
    83 #include &lt;sys/types.h&gt;
       
    84 #include &lt;sys/wait.h&gt;
       
    85 
       
    86 #define NUM_OF_PROCS 5
       
    87 
       
    88 int main(int argc, char *argv[])
       
    89 {
       
    90    if(argc != 2)
       
    91    {
       
    92       printf("\r\n One parameter is needed.  \r\n");
       
    93       
       
    94       return EXIT_FAILURE;
       
    95    }
       
    96    else
       
    97    {
       
    98       int argvAsInt = atoi(argv[1]);
       
    99       
       
   100       if(argvAsInt &gt; NUM_OF_PROCS)
       
   101       {
       
   102          printf("\r\n parameter[%d] one is out of range  \r\n",argvAsInt);
       
   103        
       
   104          return EXIT_FAILURE;
       
   105       }
       
   106       else
       
   107       {      
       
   108          if(argvAsInt == 0)
       
   109          {
       
   110             //parent process.
       
   111             pid_t Processpid[NUM_OF_PROCS];
       
   112    
       
   113             //executable points to the compiled version of this source.
       
   114             char execFileName[] = "/root/PortDoc/Example3_c/Symbian/ParentProg";
       
   115             int RetVal;
       
   116             int I;
       
   117             char iAsString[2];
       
   118             char* spawnedArgs[3];
       
   119             spawnedArgs[0] = argv[0];
       
   120             spawnedArgs[2] = NULL;
       
   121     
       
   122             for(I=1; i&lt;NUM_OF_PROCS;i++)
       
   123             {
       
   124                //store I as a string.
       
   125                bzero(iAsString,sizeof(iAsString));
       
   126                iAsString[0] = 0x30+I;
       
   127        
       
   128                spawnedArgs[1] = iAsString;
       
   129                
       
   130                RetVal= posix_spawn(&amp;Processpid[i],execFileName,NULL,NULL,spawnedArgs,NULL);
       
   131    
       
   132                //wait for chid process to terminate before spawning the next.
       
   133               (void)waitpid(Processpid[i],NULL,0);
       
   134                printf("\r\n*** Child process finished ***\r\n");
       
   135             }
       
   136          }
       
   137          else
       
   138          {
       
   139             //child process
       
   140             printf("\r\n Child Process Inst[%d] running ***\r\n",argvAsInt);
       
   141 
       
   142             //Terminate child process.
       
   143             exit(0);
       
   144          }
       
   145       }
       
   146    }
       
   147    return EXIT_SUCCESS;
       
   148 }
       
   149 </codeblock></section>
       
   150 <section><title>A lot of data passed to child</title><p>The second issue is
       
   151 where there is too much data to be passed across to the child process using
       
   152 the <xref href="GUID-E7C4DE71-BC5B-34AE-ACB3-C34A0DB1FC16.dita"><apiname>posix_spawn()</apiname></xref> call. A common work-around used in systems
       
   153 where <codeph>fork()</codeph> is not available is to use POSIX threads, or
       
   154 Pthreads. These Pthreads will execute in the same process and share their
       
   155 memory space, that is, they can share the same data objects. One critical
       
   156 difference between using Pthreads and <codeph>fork()</codeph> is that <codeph>fork()</codeph> creates
       
   157 copies of the parent's data objects in the child. The copied data objects
       
   158 can then be modified independently by both processes. However, when using
       
   159 Pthreads such data objects are shared and extra care, such as the use of mutexes
       
   160 and semaphores, is required when accessing them if their values can change. </p></section>
       
   161 </conbody></concept>