|
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 <stdio.h> |
|
43 #include <stdlib.h> |
|
44 #include <sys/types.h> |
|
45 #include <sys/wait.h> |
|
46 #include <unistd.h> |
|
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<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 <stdio.h> |
|
80 #include <stdlib.h> |
|
81 #include <strings.h> |
|
82 #include <spawn.h> |
|
83 #include <sys/types.h> |
|
84 #include <sys/wait.h> |
|
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 > 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<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(&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> |