diff -r 43e37759235e -r 51a74ef9ed63 Symbian3/SDK/Source/GUID-545DA961-217E-49CA-A90E-7A41E2C03A99.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/SDK/Source/GUID-545DA961-217E-49CA-A90E-7A41E2C03A99.dita Wed Mar 31 11:11:55 2010 +0100 @@ -0,0 +1,161 @@ + + + + + +Forking +without <codeph>exec()</codeph>A Unix-like system may create the child process using fork(), +which then does not make a subsequent exec() call. The result +of this is that the parent and child processes run the same executable. The +child may communicate with the parent using pipes. One example of a system +which does this is the email software program Exim (www.exim.org). In addition +to forking without exec(), it can also re-exec() itself +to regain dropped root privileges. +

The issues that such systems encounter when porting to P.I.P.S. fall into +two categories:

+
Little or no state data passed to child

The first +issue is where there is a little/no data passed to the child process on the fork() operation. +Many examples of this exist in pre/post forking of listening sockets in TCP +server applications, for example, in the MPM pre-fork module of the Apache +server. More details are available at http://httpd.apache.org/docs/2.2/mod/prefork.html.

This +can be resolved by using the posix_spawn() operation, and +passing any data using the argv parameters or environment +variables. For more information about the posix_spawn() operation, +see http://www.opengroup.org/. +Note that some argv parameters must be used to distinguish +the behaviour of the parent process from the subsequent behaviour of the child +when the main() function is called; the behaviour of the +child cannot be identical to the parent.

The subsequent sections provide +the following information:

    +
  • Parent process forking example

  • +
  • P.I.P.S. equivalent

  • +

+
Parent process forking example#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +#define NUM_OF_PROCS 5 + +int main(int argc, char *argv[]) +{ + pid_t Processpid[NUM_OF_PROCS]; + + int I; + + for(I=1;i<NUM_OF_PROCS;i++) + { + Processpid[i] = fork(); + + if(Processpid[i] == 0) + { + printf("\r\n Child Process Inst[%d] running ***\r\n",I); + + //Terminate child process.5 + exit(0); + } + else + { + //Wait for the child process to terminate before forking the next one. + waitpid(Processpid[i],NULL,0); + + printf("\r\n*** Child int[%d] process finished ***\r\n",I); + } + } + + return EXIT_SUCCESS; +} +

+
P.I.P.S. equivalent#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <spawn.h> +#include <sys/types.h> +#include <sys/wait.h> + +#define NUM_OF_PROCS 5 + +int main(int argc, char *argv[]) +{ + if(argc != 2) + { + printf("\r\n One parameter is needed. \r\n"); + + return EXIT_FAILURE; + } + else + { + int argvAsInt = atoi(argv[1]); + + if(argvAsInt > NUM_OF_PROCS) + { + printf("\r\n parameter[%d] one is out of range \r\n",argvAsInt); + + return EXIT_FAILURE; + } + else + { + if(argvAsInt == 0) + { + //parent process. + pid_t Processpid[NUM_OF_PROCS]; + + //executable points to the compiled version of this source. + char execFileName[] = "/root/PortDoc/Example3_c/Symbian/ParentProg"; + int RetVal; + int I; + char iAsString[2]; + char* spawnedArgs[3]; + spawnedArgs[0] = argv[0]; + spawnedArgs[2] = NULL; + + for(I=1; i<NUM_OF_PROCS;i++) + { + //store I as a string. + bzero(iAsString,sizeof(iAsString)); + iAsString[0] = 0x30+I; + + spawnedArgs[1] = iAsString; + + RetVal= posix_spawn(&Processpid[i],execFileName,NULL,NULL,spawnedArgs,NULL); + + //wait for chid process to terminate before spawning the next. + (void)waitpid(Processpid[i],NULL,0); + printf("\r\n*** Child process finished ***\r\n"); + } + } + else + { + //child process + printf("\r\n Child Process Inst[%d] running ***\r\n",argvAsInt); + + //Terminate child process. + exit(0); + } + } + } + return EXIT_SUCCESS; +} +
+
A lot of data passed to child

The second issue is +where there is too much data to be passed across to the child process using +the posix_spawn() call. A common work-around used in systems +where fork() is not available is to use POSIX threads, or +Pthreads. These Pthreads will execute in the same process and share their +memory space, that is, they can share the same data objects. One critical +difference between using Pthreads and fork() is that fork() creates +copies of the parent's data objects in the child. The copied data objects +can then be modified independently by both processes. However, when using +Pthreads such data objects are shared and extra care, such as the use of mutexes +and semaphores, is required when accessing them if their values can change.

+
\ No newline at end of file