Top Banner
1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Herbert G. Mayer, PSU Status 6/28/2015 Status 6/28/2015
49

1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

Jan 06, 2018

Download

Documents

Morgan Byrd

3 Process – SW View “A [Bryant, 16] “A process is the operating system’s abstraction of a running program.” [Silberschatz, 10] “A [Silberschatz, 10] “A process can be thought of as a program in execution …” [Silberschatz, 90] “Informally, a [Silberschatz, 90] “Informally, a process is a program in execution. … A process is more than the program code. It also includes the current activity, as represented by the value of the program counter and the contents of the processor’s registers.” “A [Tanenbaum, 72] “A process is just an executing program, including the current values of the program counter, registers, and variables.”
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

1

CS 201Computer Systems Programming

Chapter 8

Unix fork(), execve(), getpid()

Herbert G. Mayer, PSUHerbert G. Mayer, PSUStatus 6/28/2015Status 6/28/2015

Page 2: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

2

Syllabus Process, Thread, HyperthreadProcess, Thread, Hyperthread Unix ProcessUnix Process InterruptInterrupt Command Command psps Background ProcessBackground Process Command Command fork()fork() fork() fork() SampleSample Command Command execve()execve() execve() execve() SampleSample ReferencesReferences

Page 3: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

3

Process – SW View [Bryant, 16] “A“A process is the operating system’s

abstraction of a running program.” [Silberschatz, 10] “A[Silberschatz, 10] “A process can be thought of as a

program in execution …” [Silberschatz, 90] “Informally, a[Silberschatz, 90] “Informally, a process is a

program in execution. … A process is more than the program code. It also includes the current activity, as represented by the value of the program counter and the contents of the processor’s registers.”

[Tanenbaum, 72] “A“A process is just an executing program, including the current values of the program counter, registers, and variables.”

Page 4: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

4

Thread – SW View [Bryant, 947] “A[Bryant, 947] “A thread is a logical flow that runs in the

context of a process. Each thread has its own thread context, including a unique integer thread ID, stack, stack pointer, program counter, general-purpose registers, and condition codes. All threads running in a process share the entire virtual address space of that process.”

[Silberschatz, 103] “A thread, sometimes called a lightweight process, is a basic unit of CPU utilization, and consists of a program counter, a register set, and a stack space. It shares with peer threads its code section, data section, and operating-system resources such as open files and signals.”

[Tanenbaum, 81] “A thread has a program counter that keeps track of which instruction to execute next. It has registers, which hold its current working variables. It has a stack, which contains the execution history, with one frame for each procedure called, but not yet returned from. ... A thread must execute in some process”

Page 5: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

5

Thread Creation Who makes threads? You, the programmer, or the OS, Who makes threads? You, the programmer, or the OS,

following your implicit or explicit instructionsfollowing your implicit or explicit instructions Programmer understands which portions of C program are Programmer understands which portions of C program are

dependent-, and which ones are independent of other parts dependent-, and which ones are independent of other parts of the same program –which, when executed, is a processof the same program –which, when executed, is a process

MS and Intel compiler provide tools to support this analysisMS and Intel compiler provide tools to support this analysis Some C and C++ compilers provide directivesSome C and C++ compilers provide directives Directives can be hidden as comments, to be transparent to Directives can be hidden as comments, to be transparent to

other compilersother compilers See lit ref [9] for Intel’s Parallel Studio, helping programmer

eliminated threading errors in C and C++ programs Or see Intel’s [10] [12] to help programmer “to thread” SW Or Microsoft Multi-Threading support for existing C and C++

source code [11]

Page 6: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

6

Hyperthread – HW View A processor may be A processor may be single-core single-core (UP), o(UP), or have multiple

cores, the latter meaning: all processor resources are replicated; e.g. Intel Core 2 Duo

Or a processor may be single-core, hyperthreaded, e.g. Intel Pentium 4e. Hyperthreaded means that only CPU registers and APIC are replicated, but not ALU units, such as integer unit, floating-point unit, branch unit, caches, etc.

Or a processor may be multi-core, hyperthreaded, in which case each of several real cores has a hyperthread twin (or more), sharing the real core’s ALU with all hyperthreads, but each hyperthread has own register + APIC; e.g. Intel Core i7

Hyperthreading is an old idea, proposed decades ago by Digital Equipment Corp. (DEC), implemented first in silicon by Intel in 2002 on Xeon® server + Pentium® 4 desktop CPUs

Hyperthread is an overloaded term, referring to the reduced Silicon core, as well as the active SW thread executing on it

Should be named: Should be named: HypothreadHypothread since it is a thread- since it is a thread-subsubset, set, but Hyperthread IS THE accepted technical termbut Hyperthread IS THE accepted technical term

Page 7: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

7

Hyperthread – Per Intel WebsiteAbility of processor to run concurrent threads quicklyAbility of processor to run concurrent threads quickly

Some microprocessor hardware replication that creates the illusion to SW of Dual Processor (DP)

Yet such HW with some resource replication is NOT a true dual-core silicon implementation

The execution unit is still shared between multiple threads

Effect of Hyperthreading on XeonEffect of Hyperthreading on Xeon®® Processor: Processor: Average CPU utilization increases to ~50%, down from

~35% for a typical uni-processor Up to ~30% performance gain for some applications with

the same processor frequency

Hyperthreading Technology Results:Hyperthreading Technology Results:1. More performance with enabled applications1. More performance with enabled applications2. Better responsiveness with existing applications2. Better responsiveness with existing applications

Page 8: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

8

Hyperthread – Per Intel WebsiteAlmostAlmost two Logical Processors two Logical Processors

Architecture state (registers) and Architecture state (registers) and APIC* replicatedAPIC* replicated

Shares execution units, caches, Shares execution units, caches, branch prediction, control logic branch prediction, control logic and busesand buses

ProcessorExecutionResource

Adv. ProgrammableInterrupt Control

Architecture State

Adv. ProgrammableInterrupt Control

Architecture State

On-DieCaches

System Bus

*APIC: Advanced Programmable *APIC: Advanced Programmable Interrupt Controller. Handles Interrupt Controller. Handles interrupts sent to a specified logical interrupts sent to a specified logical processorprocessor

Page 9: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

9

Hyperthread Hyperthreaded core replicates in silicon all CPU resources

essential to switching fast from one thread to another Those replicated resources are registers and the APIC. ALU

units are not replicated on a hyperthread core SW hyperthreads are also threads, but execute concurrently SW hyperthreads are also threads, but execute concurrently

on HW hyperthread cores; switch is efficient due to available on HW hyperthread cores; switch is efficient due to available registers; ALU-sharing is still necessary: Only a single ALU!registers; ALU-sharing is still necessary: Only a single ALU!

This costs ~5% more HW (silicon) than a single core, but can gain up to 30% performance improvement; great ROI!

Page 10: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

10

Delta Between Process & Thread ProcessProcess is an OS-centric view of a running program. Due to the is an OS-centric view of a running program. Due to the

meaning of “running”, all machine resources are necessary to meaning of “running”, all machine resources are necessary to execute a processexecute a process

A thread is a subset of a process, not necessarily a proper subset

One purpose for threading a process is to allow continued execution of that one process, even when some part of it has to wait; e.g. one thread waits for an IO operation to finish, but another thread can continue, being independent of the IO result

Purpose for having threads execute a process is to speed up overall execution. Possible, if multiple threads of the same process are sufficiently data-independent to progress concurrently; never simultaneously on a single core!

A threaded process can –sometimes– execute faster on a single core unit due to reduced waits

Page 11: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

11

Delta Between Thread & Hyperthread A hyperthreaded core A hyperthreaded core almostalmost creates illusion of a multi- creates illusion of a multi-

core CPU, though there is only 1 complete CPUcore CPU, though there is only 1 complete CPU Enables concurrent execution on a uni-processor,

when one process thread stalls, but another is ready; switch to the other thread is cheap, since the other register set already has proper state –except the first time around

But hyperthreading (or threading) per se never allows parallel execution; only a multi-core architecture does

A System Programmer must know: On MP OS not yet tuned for hyperthreading: best disable hyperthread scheduling; else under the right (i.e. wrong) circumstances performance degradation can result:

This is the case, when the “next core to be scheduled” happens to be regularly the hyperthreaded subset-core, while leaving other real cores idle, though a real core could work instead of the hyperthread

Page 12: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

12

Unix Process Under Unix, aUnder Unix, a process is an instance of running a

program. If you execute the ancient editor ed and your colleague does too, then there are 2 --very similar– different processes running

All user a.out programs and all Unix commands, when running, become processes; commands ll and g++ my_prog.cpp create 2 different processes

Processes are visible via ps command, and even that command is a process in its own right

Issue the command ps, for process status, and you see your current processes, plus the ps processes

Issue ps –a, and you see a very detailed list, including sleeping processes

Issue the command man ps for your education

Page 13: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

13

Unix Process When a command is issued, Unix starts new

process, suspends the current OS process, generally the C-shell, until the new child process completes

Exception: background processes with & Unix identifies every process by a Process

Identification Number (PID) assigned at initiation See getpid() function calls below Unix is a timesharing system, which grants each

process time-slices Allocation of time-slices has to be fair, so that one

long process cannot make other, shorter ones, wait for extended periods (no starvation!)

Also, time-slicing has to be efficient, lest too much processing time migrates into overhead, like a typical state government

Page 14: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

14

Windows Process Under MS Windows, the process and thread Under MS Windows, the process and thread

concepts are almost identical to the ones under concepts are almost identical to the ones under Unix; see [14]Unix; see [14]

But added terms under But added terms under WindowsWindows include: include: Job objectJob object: group of processes, managed as one unit: group of processes, managed as one unit Thread poolThread pool: a collection of threads: a collection of threads FiberFiber: execution unit to be scheduled manually by a running : execution unit to be scheduled manually by a running

application –scheduled explicitly by running SWapplication –scheduled explicitly by running SW UMSUMS: User Mode Scheduling. Thread scheduling managed : User Mode Scheduling. Thread scheduling managed

by applicationby application

In CS 201 we focus on Unix process model and Unix In CS 201 we focus on Unix process model and Unix terminologyterminology

Page 15: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

15

Interrupt Def: Program interrupt is a transparent, non-scheduled

change in execution flow with specific cause outside the program, treated by an interrupt handler, ending up at the original program again

Is unpredictable: Programmer does not know that, when, why, where interrupt happens

Is unexpected: Programmer does not know when interrupt happens, or whether it happens

Cannot be pinpointed (i.e. coded) by location: Programmer does not know where such an interrupt happens

Cause is known when interrupt happens, passed to interrupt handler by HW, yet the SW program (i.e. process) does not know a-priori that it will happen; can be some external event like power-outage, or time-slice consumption (timer interrupt), numeric error

Page 16: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

16

Interrupt Requirements

After handling, execution continues at the place in the code right after the interrupt location

Challenge: if interrupt happens during execution of some very long instruction, say move of a large portion of memory by a byte-move instruction!

Challenge caused by general need of handling interrupt swiftly, more swiftly than the time needed for some long machine instructions!

Interrupt handled in a way that the program never knows it was interrupted: transparent

Page 17: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

17

Interrupt Requirements

Interrupt has to be fast, after all, the cause ,may be some catastrophic event; e.g. power outrage!

It will not be known that an interrupt has happened, except that execution ends up slower than expected; slower than if the interrupt had not happened

Summary: the SW does not see that, why, when, how often an interrupt has happed; not a programmed event

Note: x86 INT instruction is not an interrupt! Though it is named a “software interrupt” instruction; is it totally predictable, locatable!

Page 18: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

18

Process-Related Unix Commands

Page 19: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

19

Command ps Command Command ps ps without any option shows all without any option shows all

processes with the same controlling terminal and processes with the same controlling terminal and same user id as the invoker of the same user id as the invoker of the psps command command

Complex command with numerous options!Complex command with numerous options! PIDPID identifies the process, identifies the process, TTTT the controlling the controlling

terminal, terminal, SS the state, and the state, and TIMETIME the CPU time the CPU time consumed for that processconsumed for that process

[process] ps[process] ps PID TT S TIME COMMANDPID TT S TIME COMMAND 8687 pts/33 O 0:00 ps8687 pts/33 O 0:00 ps -- O running-- O running 19212 pts/33 S 0:00 –csh19212 pts/33 S 0:00 –csh -- S sleeping-- S sleeping

Page 20: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

20

Command psThe command The command ps –aps –a prints information about all active prints information about all active processes; can result in a long list, e.g.:processes; can result in a long list, e.g.:

ps –a | moreps –a | more PID TT S TIME COMMANDPID TT S TIME COMMAND 12229 Z 0:00 12229 Z 0:00 16386 Z 0:00 16386 Z 0:00 523 console S 0:00 /usr/lib/saf/ttymon -g -523 console S 0:00 /usr/lib/saf/ttymon -g -d /dev/console -l console -m ldd /dev/console -l console -m ld 19668 pts/1 S 0:00 -tcsh19668 pts/1 S 0:00 -tcsh 19691 pts/1 S 0:00 tcsh19691 pts/1 S 0:00 tcsh 19705 pts/1 S 0:07 pine19705 pts/1 S 0:07 pine 22394 pts/2 S 0:00 -bash22394 pts/2 S 0:00 -bash 22412 pts/2 S 0:06 screen22412 pts/2 S 0:06 screen. . . . . .

Page 21: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

21

Command kill To abort, AKA kill, any process in Unix whose PID To abort, AKA kill, any process in Unix whose PID

is known, issue the command is known, issue the command killkill with argument with argument -9, e.g., the -9, e.g., the -9-9 meaning “death” meaning “death” , see below:, see below:

kill –9 19186kill –9 19186 Which in this particular case was the instructor’s Which in this particular case was the instructor’s

remote shell log-in to PSU’s computer, and as a remote shell log-in to PSU’s computer, and as a result he had to log in again result he had to log in again from home from home

Process status Process status ZZ means “zombie”, typically a means “zombie”, typically a child process that has terminated, but the parent child process that has terminated, but the parent process still needs to know its termination statusprocess still needs to know its termination status

Killing a Killing a ZZ process has no effect; good so, else process has no effect; good so, else parent would never know status of terminated parent would never know status of terminated child; see [8] for detailchild; see [8] for detail

Page 22: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

22

Background Process & Some processes may run foreverSome processes may run forever Others in your environment may run for a limited Others in your environment may run for a limited

time but for quite longtime but for quite long What if you What if you do not wish to waitdo not wish to wait for long process for long process

completion before continuing with other work?completion before continuing with other work? Possible in Unix with Possible in Unix with background background processes processes

initiated by the initiated by the && command modifier, such as: command modifier, such as:run_big &run_big &

Which executes the long running program Which executes the long running program run_bigrun_big in the background; making progress in the background; making progress whenever CPU cycles are availablewhenever CPU cycles are available

Your real interactive work may proceed in parallel Your real interactive work may proceed in parallel –on a UP implied here: –on a UP implied here: but concurrently!but concurrently!

Page 23: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

23

Background Process & What happens if this program generates output, What happens if this program generates output,

such as messages to such as messages to stderrstderr?? These would be interspersed with other output These would be interspersed with other output

generated concurrently, causing confusion!generated concurrently, causing confusion! To avoid mixing of messages, To avoid mixing of messages, stderrstderr can be can be

redirected to a separate file using redirected to a separate file using >&>&g++ big_program.cpp >& my_errors &g++ big_program.cpp >& my_errors &

. . . does accomplish that. . . does accomplish that It redirects via It redirects via >&>& all output from all output from stderr stderr to a new to a new

file, named: file, named: my_errorsmy_errors . . . and then runs in the background, caused by . . . and then runs in the background, caused by && So neither the messages nor the (long running) So neither the messages nor the (long running)

background process hold you upbackground process hold you up

Page 24: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

24

Command fork() Unix Unix fork()fork() creates a new process by cloning the creates a new process by cloning the

current process issuing the current process issuing the fork()fork() commandcommand Returns 0 to child, and returns child’s PID to parentReturns 0 to child, and returns child’s PID to parent Peculiar about a child processes: it shares all attributes Peculiar about a child processes: it shares all attributes

with the forking parent process, except the process id, with the forking parent process, except the process id, AKA AKA PIDPID, the parent PID, AKA , the parent PID, AKA PPIDPPID, , lockslocks and a few and a few attributes attributes preventing infinite spawning!preventing infinite spawning!

To compile the To compile the fork()fork() command in your C program, command in your C program, #include <unistd.h>#include <unistd.h>

Code and data space of child and parent process are Code and data space of child and parent process are shared shared for reading onlyfor reading only; when the child needs to write ; when the child needs to write (stack, heap) it receives its own copy with the new (stack, heap) it receives its own copy with the new modificationsmodifications; ; AKAAKA copy-on-write copy-on-write

Spawning a new process via Spawning a new process via fork()fork() creates a second creates a second exit()exit() action; i.e. both parent and child need to exit action; i.e. both parent and child need to exit eventuallyeventually

Page 25: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

25

Sample getpid() Program getpid.cppProgram getpid.cpp below is trivial, it does:below is trivial, it does:

Inquires about its own Inquires about its own main()main() program process id program process id Runs in the background, via &Runs in the background, via & So user has a chance to monitor the process from consoleSo user has a chance to monitor the process from console And get that processes id number via Unix And get that processes id number via Unix psps command command

And by the time And by the time getpid getpid exits, it also prints its pid exits, it also prints its pid numbernumber

Just to demonstrate the Just to demonstrate the getpid()getpid() function function

Page 26: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

26

getpid.cpp Source Program// program getpid.cpp// program getpid.cpp#include <iostream.h>#include <iostream.h>//#include <unistd.h> no fork() here//#include <unistd.h> no fork() here

// I wish to get the PID of this main() program!// I wish to get the PID of this main() program!int main()int main(){ // main{ // main int pid = getpid();int pid = getpid(); int k, i;int k, i;

// // spendspend execution time, for chance to issue ps command execution time, for chance to issue ps command for ( i = 0; i < 1000000; i++ ) {for ( i = 0; i < 1000000; i++ ) { for ( int j = 0; j < 100; j++ ) {for ( int j = 0; j < 100; j++ ) { k = j;k = j; } //end for} //end for } //end for} //end for

// OK time wasted// OK time wasted // fake assignment to i: to fool optimizer!// fake assignment to i: to fool optimizer! i = k;i = k; printf( "My process id = %d\n", pid );printf( "My process id = %d\n", pid );} //end main} //end main

Page 27: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

27

getpid() Result and Output

[process] a.out &[process] a.out &[1] 24366[1] 24366[process] ps[process] ps PID TT S TIME COMMANDPID TT S TIME COMMAND 23847 pts/49 S 0:00 -csh23847 pts/49 S 0:00 -csh 24366 pts/49 O 0:00 a.out24366 pts/49 O 0:00 a.out 24375 pts/49 O 0:00 ps24375 pts/49 O 0:00 ps[process] My process id = 24366[process] My process id = 24366^C^C[1] Done a.out[1] Done a.out

Page 28: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

28

Fork() Samples Now we run several programs that demonstrate the Now we run several programs that demonstrate the fork()fork()

Linux or Unix functionLinux or Unix function Reminder of Reminder of fork()fork()

Creates child process identical to parent processCreates child process identical to parent process fork()fork() returns pid of child to parent != 0 returns pid of child to parent != 0 But returns 0 to child processBut returns 0 to child process If child process wishes to know its own pid, it must call function If child process wishes to know its own pid, it must call function

getpid()getpid() If child wishes to know parent’s process id, it must call function If child wishes to know parent’s process id, it must call function

getppid()getppid() Child process starts executing after the Child process starts executing after the fork()fork() command, command,

NOT repeating the NOT repeating the fork()fork() command command

Page 29: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

29

fork() Sample1 in C#include <unistd.h>#include <unistd.h>

#define DEAD -1#define DEAD -1

// there are no shared global data, not shared data on heap!// there are no shared global data, not shared data on heap!

void fork_sample1( void )void fork_sample1( void ){ // fork_sample1{ // fork_sample1 int local = 1; // just some data to track: which process?int local = 1; // just some data to track: which process? pid_t pid = fork(); // from now on: 2 processespid_t pid = fork(); // from now on: 2 processes switch ( pid ) {switch ( pid ) { case 0:case 0: // this is thread through child process// this is thread through child process printf( “++local value in child = %d\n", ++local );printf( “++local value in child = %d\n", ++local ); break;break; case DEAD:case DEAD: // this is en error process, dead, zombie?// this is en error process, dead, zombie? printf( “<><> local in dead process = %d\n", local );printf( “<><> local in dead process = %d\n", local ); break;break; default:default: // clearly thread through parent process// clearly thread through parent process printf( ”parent pid = %d, --local = %d\n", pid, --local );printf( ”parent pid = %d, --local = %d\n", pid, --local ); } //end switch} //end switch // strange? switch statement has multiple clauses executed! By design!// strange? switch statement has multiple clauses executed! By design! printf( "Ending process %d\n", pid );printf( "Ending process %d\n", pid );} //end fork_sample1} //end fork_sample1

Page 30: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

30

fork() Sample1 Output[process] a.out[process] a.outparent pid = 22853, --local = 0parent pid = 22853, --local = 0Ending process 22853Ending process 22853++local value in child = 2++local value in child = 2Ending process 0Ending process 0[process][process]

•Note that Note that locallocal is 2, and not 1 in child process, and it is 2, and not 1 in child process, and it happens to be executed after parent; arbitrarily!happens to be executed after parent; arbitrarily!

•So you infer: So you infer: child has its own copychild has its own copy. It does not share . It does not share locallocal with parent; else it would be 1, since parent with parent; else it would be 1, since parent decreased decreased locallocal to 0 to 0

•Students: Are other outputs possible? How many?Students: Are other outputs possible? How many?

Page 31: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

31

fork() Sample2 in C++#define DEAD -1#define DEAD -1 // define DEAD as before// define DEAD as before#include <unistd>#include <unistd> // make fork() available// make fork() available

// Bryant & O'Halleron's "Computer Systems", chapter 8// Bryant & O'Halleron's "Computer Systems", chapter 8void fork_sample2()void fork_sample2(){ // fork_sample2{ // fork_sample2 switch ( switch ( fork()fork() ) { ) { case 0:case 0: // child process// child process cout << 'C';cout << 'C'; break;break; case DEAD:case DEAD: cout << " <><> DEAD process?";cout << " <><> DEAD process?"; break;break; default:default: // parent process// parent process cout << 'P';cout << 'P'; } //end switch} //end switch // in all cases, indicate end by emitting 'E'// in all cases, indicate end by emitting 'E' cout << 'E';cout << 'E'; // note: no endl// note: no endl} //end fork_sample2} //end fork_sample2

Page 32: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

32

fork() Sample2 Output[process] a.out[process] a.outPECE[process] PECE[process] note no carriage return: no endl! note no carriage return: no endl!

• Would CEPE be possible?Would CEPE be possible?• Would EECP be possible?Would EECP be possible?• Would CPEE be possible?Would CPEE be possible?• Would PECE be possible?Would PECE be possible?• Would ECPE be possible?Would ECPE be possible?

Page 33: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

33

fork() Sample2 Output’ Challenge: How to modify fork_sample2() into Challenge: How to modify fork_sample2() into

for_sample2()’ such that:for_sample2()’ such that: The end message for the parent process will be The end message for the parent process will be pepe And for the child it will be And for the child it will be cece?? The run the modified program fork_sample2()’The run the modified program fork_sample2()’

[process] a.out[process] a.out

CPpeceCPpece or:or:CPcepeCPcepe or:or:PpeCcePpeCce or:or:CcePpeCcePpe … just few more outputs possible!… just few more outputs possible!

Page 34: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

34

fork() Sample2’ in C++void fork_sample2()’void fork_sample2()’{ // fork_sample2’{ // fork_sample2’

pid_t pid;pid_t pid; switch ( switch ( pid =pid = fork()fork() ) { ) {

case 0:case 0: // child process// child process cout << 'C';cout << 'C'; break;break; case DEAD:case DEAD: cout << " <><> DEAD process?";cout << " <><> DEAD process?"; break;break; default:default: // parent process// parent process cout << 'P';cout << 'P'; // ok to omit break// ok to omit break } //end switch} //end switch // indicate end via string "pe" or "ce"// indicate end via string "pe" or "ce" if ( pid ) {if ( pid ) {

cout << "pe";cout << "pe"; // note: no endl// note: no endl }else{}else{cout << "ce";cout << "ce"; // doesn’t catch DEAD!// doesn’t catch DEAD! } //end if} //end if

} //end fork_sample2’} //end fork_sample2’

Page 35: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

35

fork() Sample3 in C++#include <iostream.h>#include <iostream.h>#include <unistd.h>#include <unistd.h>

int main( void )int main( void ){ // main{ // main intint number = 0;number = 0; // Note number on stack// Note number on stack

if ( 0 == if ( 0 == fork()fork() ) { ) { cout << "PID: " << cout << "PID: " << getpid()getpid()

<< " child process number = "<< " child process number = " << ++number << endl;<< ++number << endl;

} //end if} //end if cout << "PID: " << cout << "PID: " << getpid()getpid()

<< " exiting with number = "<< " exiting with number = "<< --number << endl;<< --number << endl;

return 0;return 0;} //end main} //end main

// // how many output lines, students?how many output lines, students?// Which will be the different values for "number"?// Which will be the different values for "number"?

Page 36: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

36

fork() Sample3 Output[process] a.out[process] a.outPID: 5587 exiting with number = -1PID: 5587 exiting with number = -1PID: 5588 child process number = 1PID: 5588 child process number = 1PID: 5588 exiting with number = 0PID: 5588 exiting with number = 0

Page 37: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

37

fork() Sample4 –Getting Interesting#include <iostream.h>#include <iostream.h>#include <unistd.h>#include <unistd.h>

int main()int main(){ // main{ // main int number = 100; int number = 100; // Note number on stack// Note number on stack

if ( 0 == if ( 0 == fork()fork() ) { // first child creation ) { // first child creation cout << "PID: " << getpid()cout << "PID: " << getpid()

<< " 1st child, number = "<< " 1st child, number = " << ++number << endl;<< ++number << endl;

} //end if} //end if if ( 0 == if ( 0 == fork()fork() ) { // second child creation ) { // second child creation cout << "PID: " << getpid()cout << "PID: " << getpid()

<< " 2nd child. PPID: "<< " 2nd child. PPID: " << getppid() << ". ++number = "<< getppid() << ". ++number = " << ++number << endl;<< ++number << endl;

} //end if} //end if cout << "PID: " << getpid()cout << "PID: " << getpid()

<< " exiting with number = "<< " exiting with number = " << --number << endl;<< --number << endl;

return 0;return 0;} //end main} //end main

Page 38: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

38

fork() Sample4 Output[process] a.out[process] a.outPID: 4432 exiting with number = 99PID: 4432 exiting with number = 99PID: 4433 1st child, number = 101PID: 4433 1st child, number = 101PID: 4434 2nd child. PPID: 4432. ++number = 101PID: 4434 2nd child. PPID: 4432. ++number = 101PID: 4434 exiting with number = 100PID: 4434 exiting with number = 100PID: 4433 exiting with number = 100PID: 4433 exiting with number = 100[process] PID: 4435 2nd child. PPID: 4433. ++number = 102[process] PID: 4435 2nd child. PPID: 4433. ++number = 102PID: 4435 exiting with number = 101PID: 4435 exiting with number = 101

had to enter CR-LFhad to enter CR-LF[process[process] ]

Page 39: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

39

fork() Sample4 Variation#include <iostream.h>#include <iostream.h>#include <unistd.h>#include <unistd.h>int main()int main(){ // main{ // main int number = 100; int number = 100; // Note number on stack // Note number on stack

if ( 0 == if ( 0 == fork()fork() ) { // first child creation ) { // first child creation cout << "PID: " << getpid()cout << "PID: " << getpid()

<< " 1st child, number = "<< " 1st child, number = " << ++number << endl;<< ++number << endl;

} //end if} //end if if ( 0 == if ( 0 == fork()fork() ) { // second child creation ) { // second child creation cout << "PID: " << getpid()cout << "PID: " << getpid()

<< " 2nd child. PPID: << " 2nd child. PPID: "" << getppid() << ". ++number = "<< getppid() << ". ++number = " << ++number << endl;<< ++number << endl;return 0return 0; ; // Which program output now?// Which program output now?

} //end if} //end if cout << "PID: " << getpid()cout << "PID: " << getpid()

<< " exiting with number = "<< " exiting with number = "<< --number << endl;<< --number << endl;

return 0;return 0;} //end main} //end main

Page 40: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

40

fork() Sample5 –Is Interesting

#include <iostream.h>#include <iostream.h>#include <unistd.h>#include <unistd.h>

void fork_sample()void fork_sample(){ // fork_sample{ // fork_sample pid_t pid1 = pid_t pid1 = fork()fork();; // pid1 not same as getpid()// pid1 not same as getpid() pid_t pid2 = pid_t pid2 = fork()fork(); ; // pid2 not same as getpid()// pid2 not same as getpid() pid_t pid3 = pid_t pid3 = fork()fork(); ; // pid3 not same as getpid()// pid3 not same as getpid() coutcout << " pid1 = " << pid1<< " pid1 = " << pid1

<< " pid2 = " << pid2<< " pid2 = " << pid2<< " pid3 = " << pid3<< " pid3 = " << pid3<< endl;<< endl;

} //end fork_sample} //end fork_sample

int main()int main(){ // main{ // main fork_sample();fork_sample(); exit( 0 );exit( 0 );} //end main} //end main

Page 41: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

41

fork() Sample5 Output[process] a.out[process] a.outpid1 = 24583 pid2 = 24584 pid3 = 24585pid1 = 24583 pid2 = 24584 pid3 = 24585pid1 = 24583 pid2 = 24584 pid3 = 0pid1 = 24583 pid2 = 24584 pid3 = 0pid1 = 24583 pid2 = 0 pid3 = 24587pid1 = 24583 pid2 = 0 pid3 = 24587pid1 = 0 pid2 = 24586 pid3 = 24588pid1 = 0 pid2 = 24586 pid3 = 24588[process] pid1 = 24583 pid2 = 0 pid3 = 0[process] pid1 = 24583 pid2 = 0 pid3 = 0pid1 = 0 pid2 = 24586 pid3 = 0pid1 = 0 pid2 = 24586 pid3 = 0pid1 = 0 pid2 = 0 pid3 = 0pid1 = 0 pid2 = 0 pid3 = 0pid1 = 0 pid2 = 0 pid3 = 24589pid1 = 0 pid2 = 0 pid3 = 24589had to enter CR-LF, came out early!had to enter CR-LF, came out early![process] [process]

Why are there 8 lines of output?Why are there 8 lines of output?Why do you see only 7 different pid numbers?Why do you see only 7 different pid numbers?

Which is the original parent’s pid number?Which is the original parent’s pid number?Which line above is printed by original Which line above is printed by original parentparent process? process?

Page 42: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

42

fork() Sample5 Answers

Why are there 8 lines of output?Why are there 8 lines of output?8 processes:8 processes:1 parent1 parent3 child processes from parent: c1, c2, c33 child processes from parent: c1, c2, c32 child processes from c1: c12, c132 child processes from c1: c12, c131 child process from c12: c131 child process from c12: c131 child process from c2: c23 1 child process from c2: c23

Why do you see only 7 different pid numbers?Why do you see only 7 different pid numbers?original parent never acquires via getpid(), its own pid, so never prints itoriginal parent never acquires via getpid(), its own pid, so never prints it

Which is the original parent’s pid number?Which is the original parent’s pid number?not known here; not programmed in!not known here; not programmed in!

Which line above is printed by original parent process?Which line above is printed by original parent process?the one printing 3 non-zero pid numbers, happens to be first linethe one printing 3 non-zero pid numbers, happens to be first lineduring another execution, this could be a different output line numberduring another execution, this could be a different output line number

Page 43: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

43

fork() Sample6#include <iostream.h>#include <iostream.h>#include <unistd.h>#include <unistd.h>

void fork_sample()void fork_sample(){ // fork_sample{ // fork_sample pid_t pid1 = fork();pid_t pid1 = fork(); // 1// 1 pid_t pid2 = fork();pid_t pid2 = fork(); // 2// 2 pid_t pid3 = fork();pid_t pid3 = fork(); // 3// 3 pid_t pid4 = fork();pid_t pid4 = fork(); // 4// 4 printf( "I am %5d, parent= %5d,printf( "I am %5d, parent= %5d,

pid1= %5d, pid2= %5d, pid3= %5d, pid4= %5d\n”,pid1= %5d, pid2= %5d, pid3= %5d, pid4= %5d\n”, getpid(), getppid(), pid1, pid2, pid3, pid4 );getpid(), getppid(), pid1, pid2, pid3, pid4 );} //end fork_sample} //end fork_sample

int main()int main(){ // main{ // main fork_sample();fork_sample(); exit ( 0 );exit ( 0 );} //end main} //end main

Page 44: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

44

fork() Sample6 Output

I am 22255, parent= 21528, pid1= 22256, pid2= 22257, pid3= 22258, pid4= 22260I am 22255, parent= 21528, pid1= 22256, pid2= 22257, pid3= 22258, pid4= 22260I am 22260, parent= 22255, pid1= 22256, pid2= 22257, pid3= 22258, pid4= 0I am 22260, parent= 22255, pid1= 22256, pid2= 22257, pid3= 22258, pid4= 0I am 22256, parent= 22255, pid1= 0, pid2= 22259, pid3= 22261, pid4= 22264I am 22256, parent= 22255, pid1= 0, pid2= 22259, pid3= 22261, pid4= 22264I am 22258, parent= 22255, pid1= 22256, pid2= 22257, pid3= 0, pid4= 22265I am 22258, parent= 22255, pid1= 22256, pid2= 22257, pid3= 0, pid4= 22265I am 22264, parent= 22256, pid1= 0, pid2= 22259, pid3= 22261, pid4= 0I am 22264, parent= 22256, pid1= 0, pid2= 22259, pid3= 22261, pid4= 0I am 22257, parent= 22255, pid1= 22256, pid2= 0, pid3= 22263, pid4= 22268I am 22257, parent= 22255, pid1= 22256, pid2= 0, pid3= 22263, pid4= 22268I am 22261, parent= 22256, pid1= 0, pid2= 22259, pid3= 0, pid4= 22266I am 22261, parent= 22256, pid1= 0, pid2= 22259, pid3= 0, pid4= 22266I am 22265, parent= 22258, pid1= 22256, pid2= 22257, pid3= 0, pid4= 0I am 22265, parent= 22258, pid1= 22256, pid2= 22257, pid3= 0, pid4= 0I am 22259, parent= 22256, pid1= 0, pid2= 0, pid3= 22262, pid4= 22267I am 22259, parent= 22256, pid1= 0, pid2= 0, pid3= 22262, pid4= 22267I am 22266, parent= 22261, pid1= 0, pid2= 22259, pid3= 0, pid4= 0I am 22266, parent= 22261, pid1= 0, pid2= 22259, pid3= 0, pid4= 0I am 22263, parent= 22257, pid1= 22256, pid2= 0, pid3= 0, pid4= 22270I am 22263, parent= 22257, pid1= 22256, pid2= 0, pid3= 0, pid4= 22270I am 22268, parent= 22257, pid1= 22256, pid2= 0, pid3= 22263, pid4= 0I am 22268, parent= 22257, pid1= 22256, pid2= 0, pid3= 22263, pid4= 0I am 22269, parent= 22262, pid1= 0, pid2= 0, pid3= 0, pid4= 0I am 22269, parent= 22262, pid1= 0, pid2= 0, pid3= 0, pid4= 0I am 22270, parent= 22263, pid1= 22256, pid2= 0, pid3= 0, pid4= 0I am 22270, parent= 22263, pid1= 22256, pid2= 0, pid3= 0, pid4= 0I am 22267, parent= 22259, pid1= 0, pid2= 0, pid3= 22262, pid4= 0I am 22267, parent= 22259, pid1= 0, pid2= 0, pid3= 22262, pid4= 0I am 22262, parent= 22259, pid1= 0, pid2= 0, pid3= 0, pid4= 22269I am 22262, parent= 22259, pid1= 0, pid2= 0, pid3= 0, pid4= 22269

Page 45: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

45

fork() Sample6 Graph

59

67 62

69

57

68 63

70

55

56 58

64

28

60

66

6561

Shell Process

Parent Process

4 children of Parent

Page 46: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

46

Command execve() So why does the So why does the fork()fork() command exist, if all it does command exist, if all it does

is: make a copy of the current process?is: make a copy of the current process? fork()fork() is just the first step of is just the first step of creating new creating new

processesprocesses, including the execution of any Unix , including the execution of any Unix commands, but also user programs, such as commands, but also user programs, such as a.outa.out

Therefore, code and data space have to be replaced Therefore, code and data space have to be replaced to spawn off a new, separate processto spawn off a new, separate process

Unix command Unix command execve()execve() accomplishes this accomplishes this A clever resource saving: pages in memory are not A clever resource saving: pages in memory are not

duplicated for new process; only modified pages are: duplicated for new process; only modified pages are: AKA AKA copy-on-writecopy-on-write

Side-effect of any Side-effect of any fork()fork() command is eventual command is eventual execution of two returns or exits, namely of parent execution of two returns or exits, namely of parent and child process; correspondingly, and child process; correspondingly, execve()execve() command creates command creates no new return no new return or or exitexit

Page 47: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

47

execve() Samplevoid fork_exec_sample( char * argv[], char * envp[] )void fork_exec_sample( char * argv[], char * envp[] ){ // fork_exec_sample{ // fork_exec_sample

pid_t pid = pid_t pid = forkfork(); // parent + child exist now(); // parent + child exist now

if ( 0 == pid ) {if ( 0 == pid ) { // strange order of: 0 == . . . // strange order of: 0 == . . .// child process// child processcout << "run 'herb.o' program." << endl;cout << "run 'herb.o' program." << endl;// must yield complete path; giving relative path also OK// must yield complete path; giving relative path also OKif ( if ( execveexecve( "/u/herb/progs/process/herb.o", argv, envp ) < 0 ) {( "/u/herb/progs/process/herb.o", argv, envp ) < 0 ) {

cout << "Aborting " << endl;cout << "Aborting " << endl;exit( 0 );exit( 0 );

} //end if} //end if} //end if} //end ifcout << "Created process " << pid << endl;cout << "Created process " << pid << endl;

} //end fork_exec_sample} //end fork_exec_sample

int main( int argc, char * argv[], char * envp[] )int main( int argc, char * argv[], char * envp[] ){ // main{ // main

fork_exec_sample( argv, envp );fork_exec_sample( argv, envp );return 0;return 0;

} //end main} //end main

Page 48: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

48

execve() Sample, uses herb.o// new program = process to be initiated by execve()// new program = process to be initiated by execve()// source named: herb.cpp// source named: herb.cpp#include <stdio.h>#include <stdio.h>int main()int main(){ // main{ // main printf( "<> SUCCESS <> You executed Herb\n" );printf( "<> SUCCESS <> You executed Herb\n" ); return 0;return 0; // exits main()// exits main()} //end main} //end main

1.1. Compile this, and rename: Compile this, and rename: a.outa.out --> --> herb.oherb.o2.2. Move Move herb.oherb.o into directory into directory /u/herb/progs/process/u/herb/progs/process

[[process] a.out process] a.out Created process 21010 Created process 21010 students: why printed only once? students: why printed only once?run 'herb.o' program.run 'herb.o' program.[process] <> SUCCESS <> You executed Herb[process] <> SUCCESS <> You executed Herb

Page 49: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve(), getpid() Herbert G. Mayer, PSU Status 6/28/2015.

49

References1. IBM literature about Unix 8: http://www.ibm.com/developerworks/aix/library/au-speakingunix8/2. Computer Systems, a Programmer’s Perspective, Bryant and O’Halleron, Prentice Hall © 2011, 2nd

ed. 3. Modern Operating Systems, Andrew S. Tanenbaum, Prentice Hall © 2011, 2. ed. 4. Operating System Concepts, Silberschatz and Galvin, Addison Wesley © 1998, 5. ed.5. Posix Thread: https://computing.llnl.gov/tutorials/pthreads/#Thread6. Thread, Hyperthread, Process: http://decipherinfosys.com/HyperthreadedDualCore.pdf http://decipherinfosys.com/HyperthreadedDualCore.pdf 7. Intel Hyperthreading:

http://www.intel.com/technology/itj/2002/volume06issue01/vol6iss1_hyper_threading_technology.pdf

8. Zombie process: http://en.wikipedia.org/wiki/Zombie_process9. Eliminate threading errors: http://download-software.intel.com/en-us/sites/default/files/eliminate-

threading-errors_studioxe-evalguide.pdf 10. Intel Timebase Utility for multi-threading and concurrency:

http://software.intel.com/en-us/forums/topic/30422411. MS multi-threading: http://msdn.microsoft.com/en-us/library/vstudio/172d2hhw.aspx12. Threading help: http://software.intel.com/en-us/articles/automatic-parallelization-with-intel-

compilers13. Threading instructions from Intel: http://software.intel.com/en-us/articles/intel-guide-for-

developing-multithreaded-applications14. MW Windows process and thread concept:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms684841(v=vs.85).aspx