15.04.2013 Views

Core Python Programming (2nd Edition)

Core Python Programming (2nd Edition)

Core Python Programming (2nd Edition)

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

As you can see, popen() returns a file-like object; also notice that readline(), as always, preserves the<br />

NEWLINE character found at the end of a line of input text.<br />

14.5.3. os.fork(),os.exec*(),os.wait*()<br />

Without a detailed introduction to operating systems theory, we present a light introduction to processes<br />

in this section. fork() takes your single executing flow of control known as a process and creates a "fork<br />

in the road," if you will. The interesting thing is that your system takes both forksmeaning that you will<br />

have two consecutive and parallel running programs (running the same code no less because both<br />

processes resume at the next line of code immediately succeeding the fork() call).<br />

The original process that called fork() is called the parent process, and the new process created as a<br />

result of the call is known as the child process. When the child process returns, its return value is always<br />

zero; when the parent process returns, its return value is always the process identifier (aka process ID,<br />

or PID) of the child process (so the parent can keep tabs on all its children). The PIDs are the only way<br />

to tell them apart, too!<br />

We mentioned that both processes will resume immediately after the call to fork(). Because the code is<br />

the same, we are looking at identical execution if no other action is taken at this time. This is usually not<br />

the intention. The main purpose for creating another process is to run another program, so we need to<br />

take divergent action as soon as parent and child return. As we stated above, the PIDs differ, so this is<br />

how we tell them apart.<br />

The following snippet of code will look familiar to those who have experience managing processes.<br />

However, if you are new, it may be difficult to see how it works at first, but once you get it, you get it.<br />

ret = os.fork() # spawn 2 processes, both return<br />

if ret == 0: # child returns with PID of 0<br />

child_suite # child code<br />

else: # parent returns with child's PID<br />

parent_suite # parent code<br />

The call to fork() is made in the first line of code. Now both child and parent processes exist running<br />

simultaneously. The child process has its own copy of the virtual memory address space and contains an<br />

exact replica of the parent's address spaceyes, both processes are nearly identical. Recall that fork()<br />

returns twice, meaning that both the parent and the child return. You might ask, how can you tell them<br />

apart if they both return? When the parent returns, it comes back with the PID of the child process.<br />

When the child returns, it has a return value of 0. This is how we can differentiate the two processes.<br />

Using an if-else statement, we can direct code for the child to execute (i.e., the if clause) as well as<br />

the parent (the else clause). The code for the child is where we can make a call to any of the exec*()<br />

functions to run a completely different program or some function in the same program (as long as both<br />

child and parent take divergent paths of execution). The general convention is to let the children do all<br />

the dirty work while the parent either waits patiently for the child to complete its task or continues<br />

execution and checks later to see if the child finished properly.<br />

All of the exec*() functions load a file or command and execute it with an argument list (either<br />

individually given or as part of an argument list). If applicable, an environment variable dictionary can<br />

be provided for the command. These variables are generally made available to programs to provide a<br />

more accurate description of the user's current execution environment. Some of the more well-known<br />

variables include the user name, search path, current shell, terminal type, localized language, machine

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!