1 cs 201 computer systems programming chapter 8 unix fork(), execve() herbert g. mayer, psu cs...

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

Upload: bernadette-neal

Post on 19-Jan-2018

217 views

Category:

Documents


0 download

DESCRIPTION

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.”

TRANSCRIPT

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

1

CS 201Computer Systems Programming

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

Herbert G. Mayer, PSU CSHerbert G. Mayer, PSU CSStatus 2/18/2013Status 2/18/2013

Page 2: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve() Herbert G. Mayer, PSU CS Status 2/18/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 2/18/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 2/18/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 2/18/2013

5

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, sharing the real core’s ALU with a hyperthread, but each hyperthread has own register + APIC; e.g. Intel Core i7

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

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

Should be named: Should be named: HypothreadHypothread since it is a since it is a subsubsetset

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

6

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

7

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

8

Hyperthread Hyperthreaded core only replicates in HW, silicon, those CPU

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

units are not replicated on hyperthreaded 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; sharing still necessary due to single ALUregisters; sharing still necessary due to single ALU

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

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

9

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; or: “a thread is part of a process”

One purpose for threading a process is to allow continued execution, even when some part of such a process waits; e.g. one thread waits for an IO operation to finish, but another thread can continue

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. But never simultaneously on a single core!

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

10

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, if the other register set already has the proper state

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

A System Programmer needs to know: On an OS not yet tuned for hyper-threading: best disable multi-core scheduling, else under the right (i.e. the 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 the real core could work instead of the hyperthread

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

11

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 or g++ my_prog.cpp create processes

Processes are visible via ps command, and even that command is a process of 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 long list, including sleeping processes

Issue the command man ps for your education

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

12

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 original program again

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

Is unexpected: Programmer does not know when interrupt happens

Cannot be pinpointed: Programmer does not know where interrupt happens

Cause is known, passed to interrupt handler, yet the program does not know a-priori that it will happen; can be some external event like power-outage, or timer iterrupt

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

13

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 move-byte 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 ended up to be 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 14: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve() Herbert G. Mayer, PSU CS Status 2/18/2013

14

Unix Process When you issue a command, Unix starts a new

process, suspends the current 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 a time-slice 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 much processing time migrates into overhead, like a typical state government

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

15

Command ps Command Command ps ps prints information about active prints information about active

processes; key resource for System Programmerprocesses; key resource for System Programmer It is quite complex, with many optionsIt is quite complex, with many options Without any option, command shows all processes Without any option, command shows all processes

for the same user id as the one issuing the for the same user id as the one issuing the command; see below: command; see below: PIDPID identifies the process, identifies the process, TTTT the controlling terminal, the controlling terminal, SS the state, and the state, and TIMETIME the CPU time consumed for that processthe CPU time consumed 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 16: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve() Herbert G. Mayer, PSU CS Status 2/18/2013

16

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

17

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.:-9, e.g.:

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

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

18

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? Addressed in Unix with Addressed in Unix with background background processes processes

that can be initiated by the that can be initiated by the && command modifier, command modifier, such as:such as:

run_big &run_big & Which executes a long running program Which executes a long running program run_bigrun_big

but in the background; making progress whenever but in the background; making progress whenever CPU cycles are availableCPU cycles are available

Your real interactive work may proceeded in Your real interactive work may proceeded in parallel –on a UP of course: parallel –on a UP of course: concurrentlyconcurrently

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

19

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 concurrentlygenerated concurrently To avoid mixing of messages, To avoid mixing of messages, stderr stderr 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 20: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve() Herbert G. Mayer, PSU CS Status 2/18/2013

20

Command fork() Unix command Unix command fork()fork() creates a new process by creates a new process by

cloning the current process issuing the cloning the current process issuing the fork()fork() commandcommand

Peculiar about a child processes: it shares all Peculiar about a child processes: it shares all attributes with the forking parent process, except for attributes with the forking parent process, except for process id, AKA process id, AKA PIDPID, parent PID AKA , parent PID AKA PPIDPPID, , lockslocks and a few attributes and a few attributes preventing infinite spawningpreventing infinite spawning

To correctly compile the To correctly compile the fork()fork() command in your command in your C++ program, 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 ; when the child needs to write (stack, heap) it receives its own copy with the write (stack, heap) it receives its own copy with the new new modificationsmodifications; ; AKAAKA copy-on-write copy-on-write

Spawning a new process via Spawning a new process via fork()fork() creates a creates a second second exit()exit() action action

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

21

Command fork() Confusing about Confusing about fork()fork() is that it creates one new is that it creates one new

process by cloning once, but exiting twiceprocess 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 spawningpreventing infinite spawning But child processes do execute other But child processes do execute other fork()fork() Important: child and parent run concurrentlyImportant: child and parent run concurrently

If they had 2 processors, they could run in parallel, but the relative speeds are arbitrary! Make no assumptions about their speeds

Hence these 2 executions can be arbitrarily interleaved E.g. outputs can be arbitrarily interleaved, though strictly

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

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

22

fork() Sample1#define DEAD -1#define DEAD -1#include <unistd.h>#include <unistd.h> // must include for fork() // must include for fork()void fork_sample1()void fork_sample1(){ // fork_sample1{ // fork_sample1 int int local local = 1; // track: which process? = 1; // track: which process? pid_t pid = pid_t pid = fork()fork(); // from now on: 2 processes; // 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 cout << " cout << " locallocal in child = " << in child = " << ++local ++local << endl;<< endl; break;break; case DEAD:case DEAD: // this is en error process, dead, zombie?// this is en error process, dead, zombie? cout << ” cout << ” locallocal in DEAD process " << local << endl; in DEAD process " << local << endl; break;break; default:default: // clearly thread through parent process// clearly thread through parent process cout << " cout << " locallocal in parent = " << in parent = " << --local --local << endl;<< endl; } //end switch} //end switch // switch statement with multiple clauses executed!// switch statement with multiple clauses executed! cout << "Ending process " << pid << endl;cout << "Ending process " << pid << endl;} //end fork_sample1} //end fork_sample1

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

23

fork() Sample1 Output[process] a.out[process] a.out local in parent = 0local in parent = 0Ending process 16644Ending process 16644 local in child = 2local 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 parenthappens to be executed after parent

•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 24: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve() Herbert G. Mayer, PSU CS Status 2/18/2013

24

fork() Sample2#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: // is the child's thread// is the child's thread cout << 'C';cout << 'C'; break;break; case DEAD:case DEAD: cout << " <><> DEAD process?";cout << " <><> DEAD process?"; break;break; default:default: // is the parent's process// is the parent's 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 25: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve() Herbert G. Mayer, PSU CS Status 2/18/2013

25

fork() Sample2 Output[process] a.out[process] a.outPECE[process]PECE[process]

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

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

26

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

int main()int main(){ // 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 exiting with number = ”<< ” child process exiting with 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;

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

27

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

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

28

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

<< " 2nd child, number = “<< " 2nd child, 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;

} //end main} //end main

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

29

fork() Sample4 Output[process] a.out[process] a.outPID: 20543 exiting with number = 99PID: 20543 exiting with number = 99PID: 20544 1st child, number = 101PID: 20544 1st child, number = 101PID: 20545 2nd child, number = 101PID: 20545 2nd child, number = 101PID: 20545 exiting with number = 100PID: 20545 exiting with number = 100PID: 20544 exiting with number = 100PID: 20544 exiting with number = 100[process] PID: 20546 2nd child, number = 102[process] PID: 20546 2nd child, number = 102PID: 20546 exiting with number = 101PID: 20546 exiting with number = 101

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

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

30

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

31

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 32: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve() Herbert G. Mayer, PSU CS Status 2/18/2013

32

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(); pid_t pid2 = fork();pid_t pid2 = fork(); pid_t pid3 = fork();pid_t pid3 = fork(); pid_t pid4 = fork();pid_t pid4 = fork(); 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 33: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve() Herbert G. Mayer, PSU CS Status 2/18/2013

33

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

34

fork() Sample6 Graph

59

67 62

69

57

68 63

70

55

56 58

64

28

60

66

6561

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

35

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 creating new is just the first step of creating new

processes, including the execution of any Unix processes, including the execution of any Unix commands, or programs, such as commands, or 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 real non-shell processto spawn off a real non-shell 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 no new return or exitcommand creates no new return or exit

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

36

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 == . . .// this is thread through child process// this is thread through child processcout << “ run 'herb.o' program." << endl;cout << “ run 'herb.o' program." << endl;// must be complete path; a relative path is also OK// must be complete path; a relative path is 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 << "Ending process " << pid << endl;cout << "Ending 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 37: 1 CS 201 Computer Systems Programming Chapter 8 Unix fork(), execve() Herbert G. Mayer, PSU CS Status 2/18/2013

37

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 it\n" );printf( "<> SUCCESS <> You executed it\n" ); return 0;return 0;} //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 Ending process 21010Ending process 21010 run 'herb.o' program.run 'herb.o' program.[process] <> SUCCESS <> You executed it[process] <> SUCCESS <> You executed it

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

38

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/#Thread

6. 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