39
1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Herbert G. Mayer, PSU CS Status 11/17/2013 Status 11/17/2013

1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

Embed Size (px)

Citation preview

Page 1: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

1

CS 201Computer Systems Programming

Chapter 8“Unix fork(), execve()”

Herbert G. Mayer, PSU CSHerbert G. Mayer, PSU CSStatus 11/17/2013Status 11/17/2013

Page 2: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

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()” Herbert G. Mayer, PSU CS Status 11/17/2013

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()” Herbert G. Mayer, PSU CS Status 11/17/2013

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()” Herbert G. Mayer, PSU CS Status 11/17/2013

5

Thread Creation Who makes threads?Who makes threads?

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 programof the same program

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()” Herbert G. Mayer, PSU CS Status 11/17/2013

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()” Herbert G. Mayer, PSU CS Status 11/17/2013

7

Hyperthread – Per Intel Website

Ability 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()” Herbert G. Mayer, PSU CS Status 11/17/2013

8

Hyperthread – Per Intel Website

AlmostAlmost 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()” Herbert G. Mayer, PSU CS Status 11/17/2013

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()” Herbert G. Mayer, PSU CS Status 11/17/2013

10

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

Due to the meaning of “running”, all machine Due to the meaning of “running”, all machine resources are necessary to execute a processresources are necessary to execute 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()” Herbert G. Mayer, PSU CS Status 11/17/2013

11

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

multi-core CPU, though there is only 1 complete CPUmulti-core CPU, though there is only 1 complete CPU

Enables concurrent execution on a uni-processor, when one process thread stalls and another thread 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 results

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

Page 12: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

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-- 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()” Herbert G. Mayer, PSU CS Status 11/17/2013

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()” Herbert G. Mayer, PSU CS Status 11/17/2013

14

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): Programmer does not know where such an interrupt happens

Cause is known, 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 15: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

15

Interrupt After handling, execution continues at place after the

interrupt Challenge: if interrupt happens during execution of

some 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

Except that execution ends up slower than expected; slower than if the interrupt had not happened

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

Page 16: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

16

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 sleepin-- S sleepingg

Page 17: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

17

Command psThe command The command ps –aps –a prints information about all prints information about all active processes; can result in a long list, e.g.:active 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 523 console S 0:00 /usr/lib/saf/ttymon -g -d /dev/console -l console -m ld-g -d /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 18: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

18

Command ps

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 meaning “death” -9, e.g., the -9 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 19: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

19

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 do not wish to wait for long process What if you do not wish to wait 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 proceeded in Your real interactive work may proceeded in parallel –on a UP implied here: parallel –on a UP implied here: but concurrently!but concurrently!

Page 20: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

20

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 21: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

21

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 Peculiar about a child processes: it shares all

attributes with the forking parent process, except the attributes with the forking parent process, except the process id AKA process id AKA PIDPID, the parent PID AKA , the parent PID AKA PPIDPPID, , lockslocks and a few attributes and a few 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 (<- Final!)(<- Final!)

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 22: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

22

Command fork() Confusing about Confusing about fork()fork():: it creates one new process it creates one new process

by cloning once, but exiting twice!by cloning once, but exiting twice! Child can inquire about its own PID via Child can inquire about its own PID via getpid( )getpid( ) Child processes created via Child processes created via fork()fork() do not repeat do not repeat

their own their own fork()fork() thus thus preventing infinite spawning!!preventing infinite spawning!! But child processes do execute other But child processes do execute other fork()fork()

instructions, if also present in the parent program instructions, if also present in the parent program Important: child and parent run concurrentlyImportant: child and parent run concurrently

If parent and child had 2 processors, they could both run in parallel, but the relative speeds shall be arbitrary! Make no assumptions about their speeds!!

Hence on a UP these 2 executions are arbitrarily interleaved E.g. outputs can be arbitrarily mixed, though strictly

sequential for parent and strictly sequential for the child A sample shown next:A sample shown next:

Page 23: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

23

fork() Sample1 in C

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

#define DEAD -1#define DEAD -1

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

void fork_sample1()void fork_sample1(){ // 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 24: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

24

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 25: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

25

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';} //end fork_sample2} //end fork_sample2

Page 26: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

26

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 27: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

27

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: " << getpid()cout << "PID: " << getpid()

<< ” child process number = ”<< ” child process 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

// // 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 28: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

28

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 = 0 PID: 5588 exiting with number = 0

Page 29: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

29

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() << " 1st child, number = "cout << "PID: " << getpid() << " 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() << " 2nd child. PPID: "cout << "PID: " << getpid() << " 2nd child. PPID: "

<< getppid() << ". ++number = " << ++number << endl;<< getppid() << ". ++number = " << ++number << endl; } //end if} //end if cout << "PID: " << getpid()cout << "PID: " << getpid()

<< " exiting with number = " << --number << endl;<< " exiting with number = " << --number << endl; return 0;return 0;} //end main} //end main

Page 30: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

30

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 31: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

31

fork() Sample5 –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();; pid_t pid2 = pid_t pid2 = fork()fork();; pid_t pid3 = pid_t pid3 = fork()fork();; 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 32: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

32

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-LFhad to enter CR-LF[process] [process]

Page 33: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

33

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 34: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

34

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 35: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

35

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 36: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

36

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

does is: make a copy of the current process?does 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 duplicated for new process; only modified pages are: AKA are: 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 37: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

37

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 38: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

38

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 39: 1 CS 201 Computer Systems Programming Chapter 8 “Unix fork(), execve()” Herbert G. Mayer, PSU CS Status 11/17/2013

39

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, second ed. 4. Operating System Concepts, Silberschatz and Galvin, Addison Wesley © 1998, fifth 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/304224

11. 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-applications