C++ Network Programming, Volume I: Mastering Complexity with ACE and Patterns
I l @ ve RuBoard |
Motivation
Operating systems provide a variety of methods for setting the properties of newly-created processes. A new process's properties affect its relationship to other processes and its execution environment. Some of the common properties include
These alternatives involve capabilities and APIs that are often unportable, even across similar platforms. A great deal of experience and platform-specific knowledge is needed to assure that each application's process properties are expressed correctly. The ACE_Process_Options class captures this knowledge portably. Class Capabilities
The ACE_Process_Options class unifies how process properties are communicated to the ACE_Process and ACE_Process_Manager classes, which use these properties to select and influence the underlying OS process creation and environment mechanisms. ACE_Process_Options provides the following capabilities:
The interface of the ACE_Process_Options class is shown in Figure 8.3 and its key platform-independent methods are outlined in the following table:
Figure 8.3. The ACE_Process_Options Class Diagram
Section 8.2 on page 161 explained why ACE_Process offers
The ACE_Process_Options class also uses this approach. Its methods listed above offer a portable set of properties for all multiprocess platforms. The methods listed below access platform-specific properties:
These methods allow multiprocessing applications to take advantage of nonportable capabilities, without having to rewrite process property management code for each platform. Example
This section generalizes the example code from Section 8.2 as follows :
#include "ace/OS.h" #include "ace/ACE.h" #include "ace/Process.h" int main (int argc, char *argv[]) { ACE_Process_Options options; FILE *fp = 0; char *n_env = 0; int n; if (argc == 1) { // Top-level process. n_env = ACE _OS::getenv ("FACTORIAL"); n = n_env == 0 ? 0 : atoi (n_env); options.command_line ("%s %d", argv[0], n == 0 ? 10 : n); const char *working_dir = ACE_OS::getenv ("WORKING_DIR"); if (working_dir) options.working_directory (working_dir); fp = fopen ("factorial.log", "a"); options.setenv ("PROGRAM=%s", ACE::basename (argv[0])); } else { fp = fopen ("factorial.log", "a"); if (atoi (argv[l]) == 1) { fprintf (fp, "[%s%d]: base case\n", ACE_OS::getenv ("PROGRAM"), ACE_OS::getpid ()); fclose (fp); return 1; // Base case. } else { n = atoi (argv[1]); options.command_line ("%s %d", argv[0], n - 1); } } ACE_Process child; child.spawn (options); // Make the ''recursive'' call. child.wait (); int factorial = n * child.exit_code (); // Compute n factorial. fprintf (fp, "[%s %d] : %d! == %d\n", ACE_OS::getenv ("PROGRAM"), ACE_OS::getpid (), n, factorial); fclose (fp); return factorial; } Although the system functions called by the ACE_Process_Options and ACE_Process code vary considerably for different OS platforms, such as Win32 and POSIX, the code above will compile and run portably and correctly on all of them. |
I l @ ve RuBoard |