Date post: | 03-Jan-2016 |
Category: |
Documents |
Upload: | henry-bernard |
View: | 31 times |
Download: | 2 times |
2002 Prentice Hall. All rights reserved.
1
Chapter 18 – Process Management
Outline18.1 Introduction18.2 os.fork Function18.3 os.system Function and os.exec Family of Functions18.4 Controlling Process Input and Output18.5 Interprocess Communication18.6 Signal Handling18.7 Sending Signals
2002 Prentice Hall. All rights reserved.
2
18.1 Introduction
• Implement concurrency by having each task (or process) operate in a separate memory space
• Time slicing on single-processor systems divides processor time among many processes
• Operating system allocates a short execution time called a quantum to a process
• Operating system performs context switching to move processes and their dependent data in and out of memory
2002 Prentice Hall. All rights reserved.
3
18.1 Introduction
• Operating systems provides shells – programs that execute system commands on user’s behalf
• Some operating systems have built-in system commands that enable programmers to create and manage processes (e.g. Portable Operating System Interface for UNIX (POSIX) standard defines these system commands for UNIX operating systems)
2002 Prentice Hall. All rights reserved.
4
18.2 os.fork Function
• Function os.fork, available only on POSIX-compliant systems, creates a new process
• Parent process invokes os.fork• Parent process forks (creates) a child process• Each process has a unique identifying process id
number (pid)• Function os.fork’s return value
– 0 for child process
– Child’s pid for parent
2002 Prentice Hall. All rights reserved.
5
18.2 os.fork Function
Fig. 18.1 os.fork creates a new process.
Parent (original) process executes
1 Parent process calls os.fork and assigns return value to forkPID
2
Parent and child processes execute same program simultaneously
3
Parent process
forkPID = os.fork()
Parent process (forkPID is Child’s pid)
Child process (forkPID is 0)
2002 Prentice Hall.All rights reserved.
Outline6
fig18_02.py
1 # Fig. 18.2: fig18_02.py2 # Using fork to create child processes.3 4 import os5 import sys6 import time7 8 processName = "parent" # only the parent is running now9 10 print "Program executing\n\tpid: %d, processName: %s" \11 % ( os.getpid(), processName )12 13 # attempt to fork child process14 try:15 forkPID = os.fork() # create child process16 except OSError:17 sys.exit( "Unable to create new process." )18 19 if forkPID != 0: # am I parent process?20 print "Parent executing\n" + \21 "\tpid: %d, forkPID: %d, processName: %s" \22 % ( os.getpid(), forkPID, processName )23 24 elif forkPID == 0: # am I child process?25 processName = "child"26 print "Child executing\n" + \27 "\tpid: %d, forkPID: %d, processName: %s" \28 % ( os.getpid(), forkPID, processName )29 30 print "Process finishing\n\tpid: %d, processName: %s" \31 % ( os.getpid(), processName )
Indicates current process is parent
Returns pid
Creates duplicate of current processFunction os.fork raises OSError exception if new process cannot be created
Parent process
Child process has pid of 0
Indicates child process
2002 Prentice Hall.All rights reserved.
Outline7
Program executing pid: 5428, processName: parentParent executing pid: 5428, forkPID: 5429, processName: parentProcess finishing pid: 5428, processName: parentChild executing pid: 5429, forkPID: 0, processName: childProcess finishing pid: 5429, processName: child
Program executing pid: 5430, processName: parentChild executing pid: 5431, forkPID: 0, processName: childProcess finishing pid: 5431, processName: childParent executing pid: 5430, forkPID: 5431, processName: parentProcess finishing pid: 5430, processName: parent
Program executing pid: 5888, processName: parentChild executingParent executing pid: 5888, forkPID: 5889, processName: parentProcess finishing pid: 5888, processName: parent pid: 5889, forkPID: 0, processName: childProcess finishing pid: 5889, processName: child
2002 Prentice Hall.All rights reserved.
Outline8
fig18_03.py
1 # Fig. 18.3: fig18_03.py2 # Demonstrates the wait function.3 4 import os5 import sys6 import time7 import random8 9 # generate random sleep times for child processes10 sleepTime1 = random.randrange( 1, 6 )11 sleepTime2 = random.randrange( 1, 6 )12 13 # parent ready to fork first child process14 try:15 forkPID1 = os.fork() # create first child process16 except OSError:17 sys.exit( "Unable to create first child. " )18 19 if forkPID1 != 0: # am I parent process?20 21 # parent ready to fork second child process22 try: 23 forkPID2 = os.fork() # create second child process24 except OSError:25 sys.exit( "Unable to create second child." )26 27 if forkPID2 != 0: # am I parent process?28 print "Parent waiting for child processes...\n" + \29 "\tpid: %d, forkPID1: %d, forkPID2: %d" \30 % ( os.getpid(), forkPID1, forkPID2 )31
Generate random sleep times for child processes
Create first child process
Create second child process
2002 Prentice Hall.All rights reserved.
Outline9
fig18_03.py
32 # wait for any child process33 try:34 child1 = os.wait()[ 0 ] # wait returns one child’s pid35 except OSError:36 sys.exit( "No more child processes." )37 38 print "Parent: Child %d finished first, one child left." \39 % child140 41 # wait for another child process42 try:43 child2 = os.wait()[ 0 ] # wait returns other child’s pid44 except OSError:45 sys.exit( "No more child processes." )46 47 print "Parent: Child %d finished second, no children left." \48 % child249 50 elif forkPID2 == 0: # am I second child process? 51 print """Child2 sleeping for %d seconds...52 \tpid: %d, forkPID1: %d, forkPID2: %d""" \53 % ( sleepTime2, os.getpid(), forkPID1, forkPID2 )54 time.sleep( sleepTime2 ) # sleep to simulate some work55 56 elif forkPID1 == 0: # am I first child process?57 print """Child1 sleeping for %d seconds...58 \tpid: %d, forkPID1: %d""" \59 % ( sleepTime1, os.getpid(), forkPID1 )60 time.sleep( sleepTime1 ) # sleep to simulate some work
Function os.wait returns finished child’s pid
Function os.wait causes parent to wait for child process to complete execution
2002 Prentice Hall.All rights reserved.
Outline10
Child2 sleeping for 4 seconds... pid: 9578, forkPID1: 9577, forkPID2: 0Child1 sleeping for 5 seconds... pid: 9577, forkPID1: 0Parent waiting for child processes... pid: 9576, forkPID1: 9577, forkPID2: 9578Parent: Child 9578 finished first, one child left.Parent: Child 9577 finished second, no children left.
Parent waiting for child processes... pid: 9579, forkPID1: 9580, forkPID2: 9581Child1 sleeping for 1 seconds... pid: 9580, forkPID1: 0Child2 sleeping for 5 seconds... pid: 9581, forkPID1: 9580, forkPID2: 0Parent: Child 9580 finished first, one child left.Parent: Child 9581 finished second, no children left.
Parent waiting for child processes...Child1 sleeping for 4 seconds... pid: 9583, forkPID1: 0Child2 sleeping for 3 seconds... pid: 9584, forkPID1: 9583, forkPID2: 0 pid: 9582, forkPID1: 9583, forkPID2: 9584Parent: Child 9584 finished first, one child left.Parent: Child 9583 finished second, no children left.
2002 Prentice Hall.All rights reserved.
Outline11
fig18_04.py
1 # Fig. 18.4: fig18_04.py2 # Demonstrates the waitpid function.3 4 import os5 import sys6 import time7 8 # parent about to fork first child process9 try:10 forkPID1 = os.fork() # create first child process11 except OSError:12 sys.exit( "Unable to create first child. " )13 14 if forkPID1 != 0: # am I parent process?15 16 # parent about to fork second child process17 try: 18 forkPID2 = os.fork() # create second child process19 except OSError:20 sys.exit( "Unable to create second child." )21 22 if forkPID2 > 0: # am I parent process?23 print "Parent waiting for child processes...\n" + \24 "\tpid: %d, forkPID1: %d, forkPID2: %d" \25 % ( os.getpid(), forkPID1, forkPID2 )26 27 # wait for second child process explicitly28 try:29 child2 = os.waitpid( forkPID2, 0 )[ 0 ] # child’s pid30 except OSError:31 sys.exit( "No child process with pid %d." % ( forkPID2 ) )32 33 print "Parent: Child %d finished." \34 % child235
Create first child process
Create second child process
Wait explicitly for second child by specifying its pid
2002 Prentice Hall.All rights reserved.
Outline12
fig18_04.py
36 elif forkPID2 == 0: # am I second child process? 37 print "Child2 sleeping for 4 seconds...\n" + \38 "\tpid: %d, forkPID1: %d, forkPID2: %d" \39 % ( os.getpid(), forkPID1, forkPID2 )40 time.sleep( 4 )41 42 elif forkPID1 == 0: # am I first child process?43 print "Child1 sleeping for 2 seconds...\n" + \44 "\tpid: %d, forkPID1: %d" % ( os.getpid(), forkPID1 )45 time.sleep( 2 )
Parent waiting for child processes... pid: 6092, forkPID1: 6093, forkPID2: 6094Child1 sleeping for 2 seconds... pid: 6093, forkPID1: 0Child2 sleeping for 4 seconds... pid: 6094, forkPID1: 6093, forkPID2: 0Parent: Child 6094 finished.
Child1 sleeping for 2 seconds... pid: 6089, forkPID: 0Child2 sleeping for 4 seconds... pid: 6090, forkPID: 6089, forkPID2: 0Parent waiting for child processes... pid: 6088, forkPID: 6089, forkPID2: 6090Parent: Child 6090 finished.
Parent waiting for child processes...Child1 sleeping for 2 seconds... pid: 6102, forkPID: 0 pid: 6101, forkPID: 6102, forkPID2: 6103Child2 sleeping for 4 seconds... pid: 6103, forkPID: 6102, forkPID2: 0Parent: Child 6103 finished.
2002 Prentice Hall. All rights reserved.
13
18.3 os.system Function and os.exec Family of Functions
• Function os.system executes a system command using a shell and then returns control to the original process (after the command completes)
• os.exec family of functions do not return control to calling process after executing the specified command
2002 Prentice Hall.All rights reserved.
Outline14
fig18_05.py
1 # Fig. 18.5: fig18_05.py2 # Uses the system function to clear the screen.3 4 import os5 import sys6 7 def printInstructions( clearCommand ):8 os.system( clearCommand ) # clear display9 10 print """Type the text that you wish to save in this file.11 Type clear on a blank line to delete the contents of the file.12 Type quit on a blank line when you are finished.\n"""13 14 # determine operating system15 if os.name == "nt" or os.name == "dos": # Windows system16 clearCommand = "cls"17 print "You are using a Windows system."18 elif os.name == "posix": # UNIX-compatible system19 clearCommand = "clear"20 print "You are using a UNIX-compatible system."21 else:22 sys.exit( "Unsupported OS" )23 24 filename = raw_input( "What file would you like to create? " )25 26 # open file27 try:28 file = open( filename, "w+" )29 except IOError, message:30 sys.exit( "Error creating file: %s" % message )31 32 printInstructions( clearCommand )33 currentLine = ""34
Clear command depends on operating system
Function os.system executes system-specific clear command
2002 Prentice Hall.All rights reserved.
Outline15
fig18_05.py
35 # write input to file36 while currentLine != "quit\n":37 file.write( currentLine )38 currentLine = sys.stdin.readline()39 40 if currentLine == "clear\n":41 42 # seek to beginning and truncate file43 file.seek( 0, 0 )44 file.truncate()45 46 currentLine = ""47 printInstructions( clearCommand )48 49 file.close()
You are using a Windows system.What file would you like to create? welcome.txt
You are using a UNIX-compatible system.What file would you like to create? welcome.txt
Type the text that you wish to save in this file.Type clear on a blank line to delete the contents of the file.Type quit on a blank line when you are finished. This will not be written to the file.The following line will call clear.clear
Write user input to file
Truncate file if user enters clear
Call printInstructions to clear console and display instructions again
2002 Prentice Hall.All rights reserved.
Outline16
Type the text that you wish to save in this file.Type clear on a blank line to delete the contents of the file.Type quit on a blank line when you are finished.
Type the text that you wish to save in this file.Type clear on a blank line to delete the contents of the file.Type quit on a blank line when you are finished. Wilkommen!Bienvenue!Welcome!quit
Wilkommen!Bienvenue!Welcome!
2002 Prentice Hall.All rights reserved.
Outline17
fig18_07.py
1 # Fig. 18.7: fig18_07.py2 # Opens a Web page in a system-specific editor.3 4 import os5 import sys6 import urllib7 8 if len( sys.argv ) != 3:9 sys.exit( "Incorrect number of arguments." )10 11 # determine operating system and set editor command12 if os.name == "nt" or os.name == "dos":13 editor = "notepad.exe"14 elif os.name == "posix":15 editor = "vi"16 else:17 sys.exit( "Unsupported OS" )18 19 # obtain Web page and store in file20 urllib.urlretrieve( sys.argv[ 1 ], sys.argv[ 2 ] )21 22 # editor expects to receive itself as an argument23 os.execvp( editor, ( editor, sys.argv[ 2 ] ) )24 25 print "This line never executes."
fig18_07.py http://www.deitel.com/test/test.txt test.txt
This is a test file to illustratedownloading text from a file on aweb server using an HTTP connectionto the server.~~~
Program requires 2 command-line arguments: URL name and filename
Determine operating system and set appropriate editor command
Retrieve Web page and store its contents in the specified file
Replaces current process with text editor application
Function os.execvp takes two arguments: command name and its arguments
2002 Prentice Hall. All rights reserved.
19
18.3 os.system Function and os.exec Family of Functions
Function name Description
execl( path, arg0, arg1, ... ) Executes the program path with the given arguments.
execle( path, arg0, arg1, ..., environment )
Same as execl, but takes an additional
argument—the environment in which the program executes. The environment is a dictionary with keys that are environment variables and with values that are environment variable values.
execlp( path, arg0, arg1, ... ) Same as execl, but searches for executable
path in os.environ[ "PATH" ]. execv( path, arguments ) Same as execl, but arguments are contained
in a single tuple or list.
excve( path, arguments, environment )
Same as execle, but arguments are contained in a single tuple or list.
execvp( path, arguments ) Same as execlp, but arguments are contained in a single tuple or list.
execvpe( path, arguments, environment )
Same as execvp, but takes an additional
argument, environment, in which the program executes.
Fig. 18.8 exec family of functions.
2002 Prentice Hall. All rights reserved.
20
18.4 Controlling Process Input and Output
• UNIX-system users can use multiple programs together to achieve a particular result (e.g., ls | sort produces a sorted list of a directory’s contents)
2002 Prentice Hall.All rights reserved.
Outline21
fig18_09.py
1 # Fig. 18.9: fig18_09.py2 # Demonstrating popen and popen2.3 4 import os5 6 # determine operating system, then set directory-listing and7 # reverse-sort commands8 if os.name == "nt" or os.name == "dos": # Windows system9 fileList = "dir /B"10 sortReverse = "sort /R"11 elif os.name == "posix": # UNIX-compatible system12 fileList = "ls -1"13 sortReverse = "sort -r"14 else:15 sys.exit( "OS not supported by this program." )16 17 # obtain stdout of directory-listing command18 dirOut = os.popen( fileList, "r" )19 20 # obtain stdin, stdout of reverse-sort command21 sortIn, sortOut = os.popen2( sortReverse )22 23 filenames = dirOut.read() # output from directory-listing command24 25 # display output from directory-listing command26 print "Before sending to sort"27 print "(Output from ’%s’):" % fileList28 print filenames29 30 sortIn.write( filenames ) # send to stdin of sort command31 32 dirOut.close() # close stdout of directory-listing command 33 sortIn.close() # close stdin of sort command -- sends EOF34
Determine operating system to set system-specific directory-listing and reverse-sort commands
Executes command and obtains stdout stream
Executes command and obtains stdout and stdin streams
Returns directory-listing command’s output
Sends directory-listing command’s output to reverse-sort command’s stdin stream
Close stdout stream of directory-listing commandClosing stdin stream of sort command sends EOF
2002 Prentice Hall.All rights reserved.
Outline22
fig18_09.py
35 # display output from sort command36 print "After sending to sort"37 print "(Output from ’%s’):" % sortReverse38 print sortOut.read() # output from sort command39 40 sortOut.close() # close stdout of sort command
Before sending to sort(Output from 'ls -1'):fig18_02.pyfig18_03.pyfig18_04.pyfig18_05.pyfig18_07.pyfig18_09.pyfig18_10.pyfig18_14.pyfig18_15.py After sending to sort(Output from 'sort -r'):fig18_15.pyfig18_14.pyfig18_10.pyfig18_09.pyfig18_07.pyfig18_05.pyfig18_04.pyfig18_03.pyfig18_02.py
Retrieve directory list sorted in reverse order
Close sort command’s stdout stream
2002 Prentice Hall.All rights reserved.
Outline23
Before sending to sort(Output from 'dir /B'):fig18_02.pyfig18_03.pyfig18_04.pyfig18_05.pyfig18_07.pyfig18_09.pyfig18_10.pyfig18_14.pyfig18_15.py After sending to sort(Output from 'sort /R'):fig18_15.pyfig18_14.pyfig18_10.pyfig18_09.pyfig18_07.pyfig18_05.pyfig18_04.pyfig18_03.pyfig18_02.py
2002 Prentice Hall. All rights reserved.
24
18.5 Interprocess Communication
• Module os provides interface to many interprocess communication (IPC) mechanisms
• Pipe, IPC mechanism, is a file-like object that provides a one-way communication channel
• Function os.pipe creates a pipe and returns a tuple containing two file descriptors which provide read and write access to the pipe
• Functions os.read and os.write read and write the files associated with the file descriptors
2002 Prentice Hall.All rights reserved.
Outline25
fig18_10.py
1 # Fig. 18.10: fig18_10.py2 # Using os.pipe to communicate with a child process.3 4 import os5 import sys6 7 # open parent and child read/write pipes8 fromParent, toChild = os.pipe()9 fromChild, toParent = os.pipe()10 11 # parent about to fork child process12 try:13 pid = os.fork() # create child process14 except OSError:15 sys.exit( "Unable to create child process." )16 17 if pid != 0: # am I parent process?18 19 # close unnecessary pipe ends20 os.close( toParent ) 21 os.close( fromParent )22 23 # write values from 1-10 to parent’s write pipe and24 # read 10 values from child’s read pipe25 for i in range( 1, 11 ):26 os.write( toChild, str( i ) )27 print "Parent: %d," % i,28 print "Child: %s" % \29 os.read( fromChild, 64 )30 31 # close pipes32 os.close( toChild )33 os.close( fromChild )34
Open parent and child read/write pipes
Close unnecessary pipe ends for parent
Write values 1-10 to parent’s write pipe
Read values from child’s read pipe
Close remaining pipes
2002 Prentice Hall.All rights reserved.
Outline26
fig18_10.py
35 elif pid == 0: # am I child process?36 37 # close unnecessary pipe ends38 os.close( toChild )39 os.close( fromChild )40 41 # read value from parent pipe42 currentNumber = os.read( fromParent, 64 )43 44 # if we receive number from parent,45 # write number to child write pipe46 while currentNumber:47 newNumber = int( currentNumber ) * 2048 os.write( toParent, str( newNumber ) )49 currentNumber = os.read( fromParent, 64 )50 51 # close pipes52 os.close( toParent )53 os.close( fromParent )54 os._exit( 0 ) # terminate child process
Parent: 1, Child: 20Parent: 2, Child: 40Parent: 3, Child: 60Parent: 4, Child: 80Parent: 5, Child: 100Parent: 6, Child: 120Parent: 7, Child: 140Parent: 8, Child: 160Parent: 9, Child: 180Parent: 10, Child: 200
Close pipe ends unnecessary for child process
Read value from parent pipe
Write number to child write pipeRead more data from parent read pipe
Close remaining pipes
Terminates child process without any cleanup
2002 Prentice Hall. All rights reserved.
27
18.5 Interprocess Communication
Fig. 18.11 Initial stage: Original process can read and write to both pipes.
Original process
Parent pipe
Child pipe
Read end
Read end Write end
Write end
Original process can read from either parent or child pipe
Original process can write to either parent or child pipe
2002 Prentice Hall. All rights reserved.
28
18.5 Interprocess Communication
Patent process can read from parent and child pipe
Patent process can write to parent and child pipe
Child process
Parent pipe
Child pipe
Read end
Read end Write end
Write end
Parent process
Child process can read from parent
and child pipe
Child process can write to parent and child pipe
Fig. 18.12 Intermediate stage: Parent and child processes can read and write to both pipes.
2002 Prentice Hall. All rights reserved.
29
18.5 Interprocess Communication
Child process
Parent pipe
Child pipe
Read end
Read end Write end
Write end
Parent process
Fig. 18.13 Final stage: Parent and child processes close unneeded ends of the pipes.
Parent process reads from child pipe and writes to parent pipe
Child process reads from parent pipe and writes to child pipe
2002 Prentice Hall. All rights reserved.
30
18.6 Signal Handling
• Processes can communicate with signals, which are messages that operating systems deliver to programs asynchronously
• Signal processing: program receives a signal and performs an action based on that signal
• Signal handlers execute in response to signals• Every Python program has default signal handlers
2002 Prentice Hall.All rights reserved.
Outline31
fig18_14.py
1 # Fig. 18.14: fig18_14.py2 # Defining our own signal handler.3 4 import time5 import signal6 7 def stop( signalNumber, frame ):8 global keepRunning9 keepRunning -= 110 print "Ctrl-C pressed; keepRunning is", keepRunning11 12 keepRunning = 313 14 # set the handler for SIGINT to be function stop15 signal.signal( signal.SIGINT, stop )16 17 while keepRunning:18 print "Executing..."19 time.sleep( 1 )20 21 print "Program terminating..."
Executing...Executing...Ctrl-C pressed; keepRunning is 2Executing...Executing...Ctrl-C pressed; keepRunning is 1Executing...Executing...Ctrl-C pressed; keepRunning is 0Program terminating...
Module signal provides signal-handling capabilities
Signal handlers take two arguments: signal and current stack frame
Registers signal signal.SIGINT with function stop
2002 Prentice Hall. All rights reserved.
32
18.7 Sending Signals
• Executing programs can send signals to other processes
• Function os.kill sends a signal to a particular process identified by its pid
2002 Prentice Hall.All rights reserved.
Outline33
fig18_15.py
1 # Fig. 18.15: fig18_15.py2 # Sending signals to child processes using kill3 4 import os5 import signal6 import time7 import sys8 9 # handles both SIGALRM and SIGINT signals10 def parentInterruptHandler( signum, frame ):11 global pid12 global parentKeepRunning13 14 # send kill signal to child process and exit15 os.kill( pid, signal.SIGKILL ) # send kill signal16 print "Interrupt received. Child process killed."17 18 # allow parent process to terminate normally19 parentKeepRunning = 020 21 # set parent's handler for SIGINT22 signal.signal( signal.SIGINT, parentInterruptHandler )23 24 # keep parent running until child process is killed25 parentKeepRunning = 126 27 # parent ready to fork child process28 try:29 pid = os.fork() # create child process30 except OSError:31 sys.exit( "Unable to create child process." )32 33 if pid != 0: # am I parent process?34
Signal handler enables parent process to handle interrupt signal
Sends kill signal signal.SIGKILL to process with specified pid
Register parent’s handler for signal.SIGINT
2002 Prentice Hall.All rights reserved.
Outline34
fig18_15.py
35 while parentKeepRunning:36 print "Parent running. Press Ctrl-C to terminate child."37 time.sleep( 1 )38 39 elif pid == 0: # am I child process?40 41 # ignore interrupt in child process42 signal.signal( signal.SIGINT, signal.SIG_IGN )43 44 while 1:45 print "Child still executing."46 time.sleep( 1 )47 48 print "Parent terminated child process."49 print "Parent terminating normally."
Parent running. Press Ctrl-C to terminate child.Child still executing.Parent running. Press Ctrl-C to terminate child.Child still executing.Child still executing.Parent running. Press Ctrl-C to terminate child.Interrupt received. Child process killed.Parent terminated child process. Parent terminating normally.
Ignore interrupt signal in child process