diff -r ebc84c812384 -r 46218c8b8afa Symbian3/PDK/Source/GUID-545DA961-217E-49CA-A90E-7A41E2C03A99.dita --- a/Symbian3/PDK/Source/GUID-545DA961-217E-49CA-A90E-7A41E2C03A99.dita Thu Mar 11 15:24:26 2010 +0000 +++ b/Symbian3/PDK/Source/GUID-545DA961-217E-49CA-A90E-7A41E2C03A99.dita Thu Mar 11 18:02:22 2010 +0000 @@ -1,161 +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.

+ + + + + +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

  • +
  • A lot of data passed to child

  • +

+
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