[Python编程(第4版)].(Programming.Python.4th.Edition).Mark.Lutz.文字版

(yzsuai) #1

Programs generally test this result to begin different processing in the child only; this
script, for instance, runs the child function in child processes only.†


Because forking is ingrained in the Unix programming model, this script works well on
Unix, Linux, and modern Macs. Unfortunately, this script won’t work on the standard
version of Python for Windows today, because fork is too much at odds with the Win-
dows model. Python scripts can always spawn threads on Windows, and the multi
processing module described later in this chapter provides an alternative for running
processes portably, which can obviate the need for process forks on Windows in con-
texts that conform to its constraints (albeit at some potential cost in low-level control).


The script in Example 5-1 does work on Windows, however, if you use the Python
shipped with the Cygwin system (or build one of your own from source-code with
Cygwin’s libraries). Cygwin is a free, open source system that provides full Unix-like
functionality for Windows (and is described further in “More on Cygwin Python for
Windows” on page 185). You can fork with Python on Windows under Cygwin, even
though its behavior is not exactly the same as true Unix forks. Because it’s close enough
for this book’s examples, though, let’s use it to run our script live:


[C:\...\PP4E\System\Processes]$ python fork1.py
Hello from parent 7296 7920
Hello from child 7920

Hello from parent 7296 3988
Hello from child 3988

Hello from parent 7296 6796
Hello from child 6796
q

These messages represent three forked child processes; the unique identifiers of all the
processes involved are fetched and displayed with the os.getpid call. A subtle point:
the child process function is also careful to exit explicitly with an os._exit call. We’ll
discuss this call in more detail later in this chapter, but if it’s not made, the child process
would live on after the child function returns (remember, it’s just a copy of the original
process). The net effect is that the child would go back to the loop in parent and start
forking children of its own (i.e., the parent would have grandchildren). If you delete
the exit call and rerun, you’ll likely have to type more than one q to stop, because
multiple processes are running in the parent function.


In Example 5-1, each process exits very soon after it starts, so there’s little overlap in
time. Let’s do something slightly more sophisticated to better illustrate multiple forked
processes running in parallel. Example 5-2 starts up 5 copies of itself, each copy count-
ing up to 5 with a one-second delay between iterations. The time.sleep standard library


† At least in the current Python implementation, calling os.fork in a Python script actually copies the Python
interpreter process (if you look at your process list, you’ll see two Python entries after a fork). But since the
Python interpreter records everything about your running script, it’s OK to think of fork as copying your
program directly. It really will if Python scripts are ever compiled to binary machine code.


180 | Chapter 5: Parallel System Tools

Free download pdf