Chapter 2: Processes & Threads Chapter 2 Processes and threads - - PowerPoint PPT Presentation

chapter 2 processes threads
SMART_READER_LITE
LIVE PREVIEW

Chapter 2: Processes & Threads Chapter 2 Processes and threads - - PowerPoint PPT Presentation

Chapter 2: Processes & Threads Chapter 2 Processes and threads Processes Threads Scheduling Interprocess communication Classical IPC problems Chapter 2 CMPS 111, UC Santa Cruz 2 What is a process? Code, data, and


slide-1
SLIDE 1

Chapter 2

Chapter 2: Processes & Threads

slide-2
SLIDE 2

Chapter 2

2 CMPS 111, UC Santa Cruz

Processes and threads

Processes Threads Scheduling Interprocess communication Classical IPC problems

slide-3
SLIDE 3

Chapter 2

3 CMPS 111, UC Santa Cruz

What is a process?

Code, data, and stack

Usually (but not always) has its own address space

Program state

CPU registers Program counter (current location in the code) Stack pointer

Only one process can be running in the CPU at any

given time!

slide-4
SLIDE 4

Chapter 2

4 CMPS 111, UC Santa Cruz

The process model

  • Multiprogramming of four

programs

  • Conceptual model

4 independent processes Processes run sequentially

  • Only one program active at any

instant!

That instant can be very short…

A C D

Single PC (CPU’s point of view)

A B C D

Multiple PCs (process point of view)

B B

A B C D Time

slide-5
SLIDE 5

Chapter 2

5 CMPS 111, UC Santa Cruz

When is a process created?

Processes can be created in two ways

System initialization: one or more processes created when

the OS starts up

Execution of a process creation system call: something

explicitly asks for a new process

System calls can come from

User request to create a new process (system call executed

from user shell)

Already running processes

User programs System daemons

slide-6
SLIDE 6

Chapter 2

6 CMPS 111, UC Santa Cruz

When do processes end?

Conditions that terminate processes can be

Voluntary Involuntary

Voluntary

Normal exit Error exit

Involuntary

Fatal error (only sort of involuntary) Killed by another process

slide-7
SLIDE 7

Chapter 2

7 CMPS 111, UC Santa Cruz

Process hierarchies

Parent creates a child process

Child processes can create their own children

Forms a hierarchy

UNIX calls this a “process group” If a process exits, its children are “inherited” by the

exiting process’s parent

Windows has no concept of process hierarchy

All processes are created equal

slide-8
SLIDE 8

Chapter 2

8 CMPS 111, UC Santa Cruz

Blocked (waiting) Created Exit Ready Running

Process states

  • Process in one of 5 states
  • Created
  • Ready
  • Running
  • Blocked
  • Exit
  • Transitions between states
  • 1. Process enters ready queue
  • 2. Scheduler picks this process
  • 3. Scheduler picks a different

process

  • 4. Process waits for event (such as

I/O)

  • 5. Event occurs
  • 6. Process exits
  • 7. Process ended by another

process

1 5 4 3 2 7 7 6

slide-9
SLIDE 9

Chapter 2

9 CMPS 111, UC Santa Cruz

Processes in the OS

Two “layers” for processes Lowest layer of process-structured OS handles interrupts,

scheduling

Above that layer are sequential processes

Processes tracked in the process table Each process has a process table entry

Scheduler 1 N-2 N-1

Processes

slide-10
SLIDE 10

Chapter 2

10 CMPS 111, UC Santa Cruz

What’s in a process table entry?

File management

Root directory Working (current) directory File descriptors User ID Group ID

Memory management

Pointers to text, data, stack

  • r

Pointer to page table

Process management

Registers Program counter CPU status word Stack pointer Process state Priority / scheduling parameters Process ID Parent process ID Signals Process start time Total CPU usage May be stored

  • n stack
slide-11
SLIDE 11

Chapter 2

11 CMPS 111, UC Santa Cruz

What happens on a trap/interrupt?

  • 1. Hardware saves program counter (on stack or in a

special register)

  • 2. Hardware loads new PC, identifies interrupt
  • 3. Assembly language routine saves registers
  • 4. Assembly language routine sets up stack
  • 5. Assembly language calls C to run service routine
  • 6. Service routine calls scheduler
  • 7. Scheduler selects a process to run next (might be

the one interrupted…)

  • 8. Assembly language routine loads PC & registers

for the selected process

slide-12
SLIDE 12

Chapter 2

12 CMPS 111, UC Santa Cruz

Threads: “processes” sharing memory

Process == address space Thread == program counter / stream of instructions Two examples

Three processes, each with one thread One process with three threads

Kernel Kernel Threads Threads

System space User space Process 1 Process 2 Process 3 Process 1

slide-13
SLIDE 13

Chapter 2

13 CMPS 111, UC Santa Cruz

Process & thread information

Per process items

Address space Open files Child processes Signals & handlers Accounting info Global variables

Per thread items

Program counter Registers Stack & stack pointer State

Per thread items

Program counter Registers Stack & stack pointer State

Per thread items

Program counter Registers Stack & stack pointer State

slide-14
SLIDE 14

Chapter 2

14 CMPS 111, UC Santa Cruz

Threads & stacks

Kernel Process Thread 1 Thread 2 Thread 3 Thread 1’s stack Thread 3’s stack Thread 2’s stack User space

=> Each thread has its own stack!

slide-15
SLIDE 15

Chapter 2

15 CMPS 111, UC Santa Cruz

Why use threads?

Allow a single application

to do many things at once

Simpler programming model Less waiting

Threads are faster to create

  • r destroy

No separate address space

Overlap computation and

I/O

Could be done without

threads, but it’s harder

Example: word processor

Thread to read from keyboard Thread to format document Thread to write to disk

Kernel

When in the Course of human events, it becomes necessary for one people to dissolve the political bands which have connected them with another, and to assume among the powers of the earth, the separate and equal station to which the Laws of Nature and of Nature's God entitle them, a decent respect to the

  • pinions of mankind requires that they

should declare the causes which impel them to the separation. We hold these truths to be self-evident, that all men are created equal, that they are endowed by their Creator with certain unalienable Rights, that among these are Life, Liberty and the pursuit of Happiness.--That to secure these rights, Governments are instituted among Men, deriving their just powers from the consent of the governed, --That whenever any Form of Government becomes destructive of these ends, it is the Right

  • f the People to alter or to abolish it,

and to institute new Government, laying its foundation on such principles and

  • rganizing its powers in such form, as

to them shall seem most likely to effect their Safety and Happiness. Prudence, indeed, will dictate that Governments long established should not be changed for light and transient causes; and accordingly all

slide-16
SLIDE 16

Chapter 2

16 CMPS 111, UC Santa Cruz

Multithreaded Web server

Kernel

Network connection

Dispatcher thread Worker thread Web page cache while(TRUE) { getNextRequest(&buf); handoffWork(&buf); } while(TRUE) { waitForWork(&buf); lookForPageInCache(&buf,&page); if(pageNotInCache(&page)) { readPageFromDisk(&buf,&page); } returnPage(&page); }

slide-17
SLIDE 17

Chapter 2

17 CMPS 111, UC Santa Cruz

Three ways to build a server

Thread model

Parallelism Blocking system calls

Single-threaded process: slow, but easier to do

No parallelism Blocking system calls

Finite-state machine

Each activity has its own state States change when system calls complete or interrupts

  • ccur

Parallelism Nonblocking system calls Interrupts

slide-18
SLIDE 18

Chapter 2

18 CMPS 111, UC Santa Cruz

Implementing threads

Kernel

Run-time system Thread table Process table

Kernel

Thread Process Thread table Process table

User-level threads + No need for kernel support

  • May be slower than kernel threads
  • Harder to do non-blocking I/O

Kernel-level threads + More flexible scheduling + Non-blocking I/O

  • Not portable
slide-19
SLIDE 19

Chapter 2

19 CMPS 111, UC Santa Cruz

Scheduling

What is scheduling?

Goals Mechanisms

Scheduling on batch systems Scheduling on interactive systems Other kinds of scheduling

Real-time scheduling

slide-20
SLIDE 20

Chapter 2

20 CMPS 111, UC Santa Cruz

Why schedule processes?

Bursts of CPU usage alternate with periods of I/O wait Some processes are CPU-bound: they don’t many I/O

requests

Other processes are I/O-bound and make many kernel

requests

CPU bound I/O bound CPU bursts I/O waits

Total CPU usage Total CPU usage

Time

slide-21
SLIDE 21

Chapter 2

21 CMPS 111, UC Santa Cruz

When are processes scheduled?

At the time they enter the system

Common in batch systems Two types of batch scheduling

Submission of a new job causes the scheduler to run Scheduling only done when a job voluntarily gives up the CPU

(i.e., while waiting for an I/O request)

At relatively fixed intervals (clock interrupts)

Necessary for interactive systems May also be used for batch systems Scheduling algorithms at each interrupt, and picks the next

process from the pool of “ready” processes

slide-22
SLIDE 22

Chapter 2

22 CMPS 111, UC Santa Cruz

Scheduling goals

All systems

Fairness: give each process a fair share of the CPU Enforcement: ensure that the stated policy is carried out Balance: keep all parts of the system busy

Batch systems

Throughput: maximize jobs per unit time (hour) Turnaround time: minimize time users wait for jobs CPU utilization: keep the CPU as busy as possible

Interactive systems

Response time: respond quickly to users’ requests Proportionality: meet users’ expectations

Real-time systems

Meet deadlines: missing deadlines is a system failure! Predictability: same type of behavior for each time slice

slide-23
SLIDE 23

Chapter 2

23 CMPS 111, UC Santa Cruz

Measuring scheduling performance

Throughput

Amount of work completed per second (minute, hour) Higher throughput usually means better utilized system

Response time

Response time is time from when a command is submitted until results

are returned

Can measure average, variance, minimum, maximum, … May be more useful to measure time spent waiting

Turnaround time

Like response time, but for batch jobs (response is the completion of

the process)

Usually not possible to optimize for all metrics with the same

scheduling algorithm

slide-24
SLIDE 24

Chapter 2

24 CMPS 111, UC Santa Cruz

First Come, First Served (FCFS)

Goal: do jobs in the order

they arrive

Fair in the same way a bank

teller line is fair

Simple algorithm! Problem: long jobs delay

every job after them

Many processes may wait for

a single long job A B C D 4 3 6 3 Current job queue Execution order FCFS scheduler A B C D 4 3 6 3

slide-25
SLIDE 25

Chapter 2

25 CMPS 111, UC Santa Cruz

Shortest Job First (SJF)

Goal: do the shortest job

first

Short jobs complete first Long jobs delay every job

after them

Jobs sorted in increasing

  • rder of execution time

Ordering of ties doesn’t

matter

Shortest Remaining Time

First (SRTF): preemptive form of SJF

Problem: how does the

scheduler know how long a job will take?

A B C D 4 3 6 3 A B C D 4 3 6 3 Current job queue Execution order SJF scheduler

slide-26
SLIDE 26

Chapter 2

26 CMPS 111, UC Santa Cruz

Three-level scheduling

CPU Main memory

CPU scheduler Memory scheduler Admission scheduler Input queue Arriving jobs

Jobs held in input queue until moved into memory

Pick “complementary jobs”: small & large, CPU- & I/O-intensive Jobs move into memory when admitted

CPU scheduler picks next job to run Memory scheduler picks some jobs from main memory and

moves them to disk if insufficient memory space

slide-27
SLIDE 27

Chapter 2

27 CMPS 111, UC Santa Cruz

Round Robin (RR) scheduling

Round Robin scheduling

Give each process a fixed

time slot (quantum)

Rotate through “ready”

processes

Each process makes some

progress

What’s a good quantum?

Too short: many process

switches hurt efficiency

Too long: poor response to

interactive requests

Typical length: 10–50 ms

A B C D E Time

A B C D E

slide-28
SLIDE 28

Chapter 2

28 CMPS 111, UC Santa Cruz

Priority scheduling

  • Assign a priority to each process

“Ready” process with highest

priority allowed to run

Running process may be

interrupted after its quantum expires

  • Priorities may be assigned

dynamically

Reduced when a process uses

CPU time

Increased when a process waits

for I/O

  • Often, processes grouped into

multiple queues based on priority, and run round-robin per queue Priority 4 Priority 3 Priority 2 Priority 1 High Low “Ready” processes

slide-29
SLIDE 29

Chapter 2

29 CMPS 111, UC Santa Cruz

Shortest process next

Run the process that will finish the soonest

In interactive systems, job completion time is unknown!

Guess at completion time based on previous runs

Update estimate each time the job is run Estimate is a combination of previous estimate and most

recent run time

Not often used because round robin with priority

works so well!

slide-30
SLIDE 30

Chapter 2

30 CMPS 111, UC Santa Cruz

Lottery scheduling

Give processes “tickets” for CPU time

More tickets => higher share of CPU

Each quantum, pick a ticket at random

If there are n tickets, pick a number from 1 to n Process holding the ticket gets to run for a quantum

Over the long run, each process gets the CPU m/n of

the time if the process has m of the n existing tickets

Tickets can be transferred

Cooperating processes can exchange tickets Clients can transfer tickets to server so it can have a higher

priority

slide-31
SLIDE 31

Chapter 2

31 CMPS 111, UC Santa Cruz

Policy versus mechanism

Separate what may be done from how it is done

Mechanism allows

Priorities to be assigned to processes CPU to select processes with high priorities

Policy set by what priorities are assigned to processes

Scheduling algorithm parameterized

Mechanism in the kernel Priorities assigned in the kernel or by users

Parameters may be set by user processes

Don’t allow a user process to take over the system! Allow a user process to voluntarily lower its own priority Allow a user process to assign priority to its threads

slide-32
SLIDE 32

Chapter 2

32 CMPS 111, UC Santa Cruz

Scheduling user-level threads

Kernel

Run-time system Thread table Process table

Kernel picks a process to

run next

Run-time system (at user

level) schedules threads

Run each thread for less than

process quantum

Example: processes get 40ms

each, threads get 10ms each

Example schedule:

A1,A2,A3,A1,B1,B3,B2,B3

Not possible:

A1,A2,B1,B2,A3,B3,A2,B1

Process A Process B

slide-33
SLIDE 33

Chapter 2

33 CMPS 111, UC Santa Cruz

Scheduling user-level threads

Kernel schedules each

thread

No restrictions on ordering May be more difficult for

each process to specify priorities

Example schedule:

A1,A2,A3,A1,B1,B3,B2,B3

Also possible:

A1,A2,B1,B2,A3,B3,A2,B1

Process A Process B

Kernel

Thread table Process table

slide-34
SLIDE 34

Chapter 2

Chapter 2: Processes & Threads

Part 2: Interprocess Communication & Synchronization

slide-35
SLIDE 35

Chapter 2

35 CMPS 111, UC Santa Cruz

Why do we need IPC?

Each process operates sequentially All is fine until processes want to share data

Exchange data between multiple processes Allow processes to navigate critical regions Maintain proper sequencing of actions in multiple

processes

These issues apply to threads as well

Threads can share data easily (same address space) Other two issues apply to threads

slide-36
SLIDE 36

Chapter 2

36 CMPS 111, UC Santa Cruz

Shared variables

const int n; typedef … Item; Item buffer[n]; int in = 0, out = 0, counter = 0;

Atomic statements:

Counter += 1; Counter -= 1;

Consumer

Item citm; while (1) { while (counter == 0) ; citm = buffer[out];

  • ut = (out+1) % n;

counter -= 1; … consume the item in citm … }

Producer

Item pitm; while (1) { … produce an item into pitm … while (counter == n) ; buffer[in] = pitm; in = (in+1) % n; counter += 1; }

Example: bounded buffer problem

slide-37
SLIDE 37

Chapter 2

37 CMPS 111, UC Santa Cruz

Problem: race conditions

Cooperating processes

share storage (memory)

Both may read and write

the shared memory

Problem: can’t guarantee

that read followed by write is atomic

Ordering matters!

This can result in erroneous

results!

We need to eliminate race

conditions…

R1 <= x R1 = R1+1 R1 => x R3 <= x R3 = R3+1 R3 => x

P1 P2 x=3 x=5

R1 <= x R1 = R1+1 R1 => x R3 <= x R3 = R3+1 R3 => x

x=6!

slide-38
SLIDE 38

Chapter 2

38 CMPS 111, UC Santa Cruz

Critical regions

  • Use critical regions to provide mutual exclusion and help fix race conditions
  • Four conditions to provide mutual exclusion
  • No two processes simultaneously in critical region
  • No assumptions made about speeds or numbers of CPUs
  • No process running outside its critical region may block another process
  • No process must wait forever to enter its critical region

Process A Process B

B blocked A enters critical region B tries to enter critical region B enters critical region A leaves critical region B leaves critical region Time

slide-39
SLIDE 39

Chapter 2

39 CMPS 111, UC Santa Cruz

Busy waiting: strict alternation

Use a shared variable (turn) to keep track of whose turn it is Waiting process continually reads the variable to see if it can

proceed

This is called a spin lock because the waiting process “spins” in a tight

loop reading the variable

Avoids race conditions, but doesn’t satisfy criterion 3 for

critical regions

while (TRUE) { while (turn != 0) ; /* loop */ critical_region (); turn = 1; noncritical_region (); } while (TRUE) { while (turn != 1) ; /* loop */ critical_region (); turn = 0; noncritical_region (); }

Process 0 Process 1

slide-40
SLIDE 40

Chapter 2

40 CMPS 111, UC Santa Cruz

Busy waiting: working solution

#define FALSE #define TRUE 1 #define N 2 // # of processes int turn; // Whose turn is it? int interested[N]; // Set to 1 if process j is interested void enter_region(int process) { int other = 1-process; // # of the other process interested[process] = TRUE; // show interest turn = process; // Set it to my turn while (turn==process && interested[other]==TRUE) ; // Wait while the other process runs } void leave_region (int process) { interested[process] = FALSE; // I’m no longer interested }

slide-41
SLIDE 41

Chapter 2

41 CMPS 111, UC Santa Cruz

i n tn ; / / #

  • f

p rocesses i n tchoos ing [n ] ; i n tnumber [n ] ;

Bakery algorithm for many processes

Notation used

<<< is lexicographical order on (ticket#, process ID) (a,b) <<< (c,d) if (a<c) or ((a==c) and (b<d)) Max(a0,a1,…,an-1) is a number k such that k>=ai for all I

Shared data

choosing initialized to 0 number initialized to 0

slide-42
SLIDE 42

Chapter 2

42 CMPS 111, UC Santa Cruz

Bakery algorithm: code

while (1) { // i is the number of the current process choosing[i] = 1; number[i] = max(number[0],number[1],…,number[n-1]) + 1; choosing[i] = 0; for (j = 0; j < n; j++) { while (choosing[j]) // wait while j is choosing a ; // number // Wait while j wants to enter and has a better number // than we do. In case of a tie, allow j to go if // its process ID is lower than ours while ((number[j] != 0) && ((number[j] < number[i]) || ((number[j] == number[i]) && (j < i)))) ; } // critical section number[i] = 0; // rest of code }

slide-43
SLIDE 43

Chapter 2

43 CMPS 111, UC Santa Cruz

Hardware for synchronization

Prior methods work, but…

May be somewhat complex Require busy waiting: process spins in a loop waiting for

something to happen, wasting CPU time

Solution: use hardware Several hardware methods

Test & set: test a variable and set it in one instruction Atomic swap: switch register & memory in one instruction Turn off interrupts: process won’t be switched out unless

it asks to be suspended

slide-44
SLIDE 44

Chapter 2

44 CMPS 111, UC Santa Cruz

Code for process Pi

wh i l e (1 ) { wh i l e (Tes tAndSet ( l

  • ck

) ) ; / / c r i t i ca l sec t i

  • n

l

  • ck

= ; / / r ema inde r

  • f

code }

Code for process Pi

wh i l e (1 ) { wh i l e (Swap( l

  • ck

,1 ) == 1 ) ; / / c r i t i ca l sec t i

  • n

l

  • ck

= ; / / r ema inde r

  • f

code } i n tl

  • ck

= ;

Mutual exclusion using hardware

Single shared variable lock Still requires busy waiting,

but code is much simpler

Two versions

Test and set Swap

Works for any number of

processes

Possible problem with

requirements

Non-concurrent code can lead

to unbounded waiting

slide-45
SLIDE 45

Chapter 2

45 CMPS 111, UC Santa Cruz

Eliminating busy waiting

Problem: previous solutions waste CPU time

Both hardware and software solutions require spin locks Allow processes to sleep while they wait to execute their critical

sections

Problem: priority inversion (higher priority process waits for

lower priority process)

Solution: use semaphores

Synchronization mechanism that doesn’t require busy waiting

Implementation

Semaphore S accessed by two atomic operations

Down(S): while (S<=0) {}; S-= 1; Up(S): S+=1;

Down() is another name for P() Up() is another name for V() Modify implementation to eliminate busy wait from Down()

slide-46
SLIDE 46

Chapter 2

46 CMPS 111, UC Santa Cruz

Critical sections using semaphores

Code for process Pi

wh i l e (1 ) { down(mu tex ) ; / / c r i t i ca l sec t i

  • n

up (mu tex ) ; / / r ema inde r

  • f

code }

Shared variables

Semaphore mu t ex ;

Define a class called

Semaphore

Class allows more complex

implementations for semaphores

Details hidden from processes

Code for individual process

is simple

slide-47
SLIDE 47

Chapter 2

47 CMPS 111, UC Santa Cruz

class Semaphore { int value; ProcessList pl; void down (); void up (); };

Semaphore code

Semaphore::down () { value -= 1; if (value < 0) { // add this process to pl Sleep (); } } Semaphore::up () { Process P; value += 1; if (value <= 0) { // remove a process P // from pl Wakeup (P); } }

Implementing semaphores with blocking

Assume two operations:

Sleep(): suspends current

process

Wakeup(P): allows process P

to resume execution

Semaphore is a class

Track value of semaphore Keep a list of processes

waiting for the semaphore

Operations still atomic

slide-48
SLIDE 48

Chapter 2

48 CMPS 111, UC Santa Cruz

Process P0

. . . / / Execu te code f

  • r

A f l ag .up ( ) ;

Process P1

. . . f l ag .down ( ) ; / / Execu te code f

  • r

B

Shared variables

/ / f l ag i n i t i a l i zed t

  • Semaphore

f l ag;

Semaphores for general synchronization

We want to execute B in P1 only after A executes in P0 Use a semaphore initialized to 0 Use up() to notify P1 at the appropriate time

slide-49
SLIDE 49

Chapter 2

49 CMPS 111, UC Santa Cruz

Types of semaphores

Two different types of semaphores

Counting semaphores Binary semaphores

Counting semaphore

Value can range over an unrestricted range

Binary semaphore

Only two values possible

1 means the semaphore is available 0 means a process has acquired the semaphore

May be simpler to implement

Possible to implement one type using the other

slide-50
SLIDE 50

Chapter 2

50 CMPS 111, UC Santa Cruz

Monitors

A monitor is another kind of high-level synchronization

primitive

One monitor has multiple entry points Only one process may be in the monitor at any time Enforces mutual exclusion - less chance for programming errors

Monitors provided by high-level language

Variables belonging to monitor are protected from simultaneous

access

Procedures in monitor are guaranteed to have mutual exclusion

Monitor implementation

Language / compiler handles implementation Can be implemented using semaphores

slide-51
SLIDE 51

Chapter 2

51 CMPS 111, UC Santa Cruz

monitor mon { int foo; int bar; double arr[100]; void proc1(…) { } void proc2(…) { } void mon() { // initialization code } };

Monitor usage

This looks like C++ code, but it’s not supported by C++ Provides the following features:

Variables foo, bar, and arr are accessible only by proc1 & proc2 Only one process can be executing in either proc1 or proc2 at any time

slide-52
SLIDE 52

Chapter 2

52 CMPS 111, UC Santa Cruz

Condition variables in monitors

Problem: how can a process wait inside a monitor?

Can’t simply sleep: there’s no way for anyone else to enter Solution: use a condition variable

Condition variables support two operations

Wait(): suspend this process until signaled Signal(): wake up exactly one process waiting on this

condition variable

If no process is waiting, signal has no effect Signals on condition variables aren’t “saved up”

Condition variables are only usable within monitors

Process must be in monitor to signal on a condition

variable

Question: which process gets the monitor after Signal()?

slide-53
SLIDE 53

Chapter 2

53 CMPS 111, UC Santa Cruz

Monitor semantics

  • Problem: P signals on condition variable X, waking Q

Both can’t be active in the monitor at the same time Which one continues first?

  • Mesa semantics

Signaling process (P) continues first Q resumes when P leaves the monitor Seems more logical: why suspend P when it signals?

  • Hoare semantics

Awakened process (Q) continues first P resumes when Q leaves the monitor May be better: condition that Q wanted may no longer hold when P leaves the

monitor

slide-54
SLIDE 54

Chapter 2

54 CMPS 111, UC Santa Cruz

Locks & condition variables

  • Monitors require native language support
  • Provide monitor support using special data types and procedures

Locks (Acquire(), Release()) Condition variables (Wait(), Signal())

  • Lock usage

Acquiring a lock == entering a monitor Releasing a lock == leaving a monitor

  • Condition variable usage

Each condition variable is associated with exactly one lock Lock must be held to use condition variable Waiting on a condition variable releases the lock implicitly Returning from Wait() on a condition variable reacquires the lock

slide-55
SLIDE 55

Chapter 2

55 CMPS 111, UC Santa Cruz

class Lock { Semaphore mutex(1); Semaphore next(0); int nextCount = 0; }; Lock::Acquire() { mutex.down(); } Lock::Release() { if (nextCount > 0) next.up(); else mutex.up(); }

Implementing locks with semaphores

Use mutex to ensure

exclusion within the lock bounds

Use next to give lock to

processes with a higher priority (why?)

nextCount indicates

whether there are any higher priority waiters

slide-56
SLIDE 56

Chapter 2

56 CMPS 111, UC Santa Cruz

class Condition { Lock *lock; Semaphore condSem(0); int semCount = 0; }; Condition::Wait () { semCount += 1; if (lock->nextCount > 0) lock->next.up(); else lock->mutex.up(); condSem.down (); semCount -= 1; } Condition::Signal () { if (semCount > 0) { lock->nextCount += 1; condSem.up (); lock->next.down (); lock->nextCount -= 1; } }

Are these Hoare or Mesa

semantics?

Can there be multiple

condition variables for a single Lock?

Implementing condition variables

slide-57
SLIDE 57

Chapter 2

57 CMPS 111, UC Santa Cruz

Message passing

Synchronize by exchanging messages Two primitives:

Send: send a message Receive: receive a message Both may specify a “channel” to use

Issue: how does the sender know the receiver got the

message?

Issue: authentication

slide-58
SLIDE 58

Chapter 2

58 CMPS 111, UC Santa Cruz

Barriers

Used for synchronizing multiple processes Processes wait at a “barrier” until all in the group arrive After all have arrived, all processes can proceed May be implemented using locks and condition variables

B and D at barrier A B C D All at barrier A B C D Barrier releases all processes A B C D Processes approaching barrier A B C D

slide-59
SLIDE 59

Chapter 2

59 CMPS 111, UC Santa Cruz

Process P0

A.down( ) ; B.down( ) ; . . . B.up ( ) ; A.up ( ) ;

Process P1

B.down( ) ; A.down( ) ; . . . A.up ( ) ; B.up ( ) ;

Shared variables

Semaphore A (1) ,B (1 ) ;

Deadlock and starvation

  • Deadlock: two or more processes are

waiting indefinitely for an event that can only by caused by a waiting process

  • P0 gets A, needs B
  • P1 gets B, needs A
  • Each process waiting for the other to

signal

  • Starvation: indefinite blocking
  • Process is never removed from the

semaphore queue in which its suspended

  • May be caused by ordering in queues

(priority)

slide-60
SLIDE 60

Chapter 2

60 CMPS 111, UC Santa Cruz

Classical synchronization problems

  • Bounded Buffer

Multiple producers and consumers Synchronize access to shared buffer

  • Readers & Writers

Many processes that may read and/or write Only one writer allowed at any time Many readers allowed, but not while a process is writing

  • Dining Philosophers

Resource allocation problem N processes and limited resources to perform sequence of tasks

  • Goal: use semaphores to implement solutions to these problems
slide-61
SLIDE 61

Chapter 2

61 CMPS 111, UC Santa Cruz

Producer

int in = 0; Item pitem; while (1) { // produce an item // into pitem empty.down(); mutex.down(); buffer[in] = pitem; in = (in+1) % n; mutex.up(); full.up(); } const int n; Semaphore empty(n),full(0),mutex(1); Item buffer[n];

Consumer

int out = 0; Item citem; while (1) { full.down(); mutex.down(); citem = buffer[out];

  • ut = (out+1) % n;

mutex.up(); empty.up(); // consume item from // citem }

Bounded buffer problem

Goal: implement producer-consumer without busy waiting

slide-62
SLIDE 62

Chapter 2

62 CMPS 111, UC Santa Cruz

Readers-writers problem

Reader process

… mutex.down(); nreaders += 1; if (nreaders == 1) // wait if writing.down(); // 1st reader mutex.up(); // Read some stuff mutex.down(); nreaders -= 1; if (nreaders == 0) // signal if writing.up(); // last reader mutex.up(); …

Shared variables

int nreaders; Semaphore mutex(1), writing(1);

Writer process

… writing.down(); // Write some stuff writing.up(); …

slide-63
SLIDE 63

Chapter 2

63 CMPS 111, UC Santa Cruz

Dining Philosophers

N philosophers around a

table

All are hungry All like to think

N chopsticks available

1 between each pair of

philosophers

Philosophers need two

chopsticks to eat

Philosophers alternate

between eating and thinking

Goal: coordinate use of

chopsticks

slide-64
SLIDE 64

Chapter 2

64 CMPS 111, UC Santa Cruz

Code for philosopher i

while(1) { chopstick[i].down(); chopstick[(i+1)%n].down(); // eat chopstick[i].up(); chopstick[(i+1)%n].up(); // think }

Shared variables

const int n; // initialize to 1 Semaphore chopstick[n];

Dining Philosophers: solution 1

Use a semaphore for each

chopstick

A hungry philosopher

Gets the chopstick to his right Gets the chopstick to his left Eats Puts down the chopsticks

Potential problems?

Deadlock Fairness

slide-65
SLIDE 65

Chapter 2

65 CMPS 111, UC Santa Cruz

Code for philosopher i

int i1,i2; while(1) { if (i != (n-1)) { i1 = i; i2 = i+1; } else { i1 = 0; i2 = n-1; } chopstick[i1].down(); chopstick[i2].down(); // eat chopstick[i1].up(); chopstick[i2].up(); // think }

Shared variables

const int n; // initialize to 1 Semaphore chopstick[n];

Dining Philosophers: solution 2

Use a semaphore for each

chopstick

A hungry philosopher

Gets lower, then higher

numbered chopstick

Eats Puts down the chopsticks

Potential problems?

Deadlock Fairness

slide-66
SLIDE 66

Chapter 2

66 CMPS 111, UC Santa Cruz

Dining philosophers with locks

Shared variables

const int n; // initialize to THINK int state[n]; Lock mutex; // use mutex for self Condition self[n];

Code for philosopher j

while (1) { // pickup chopstick mutex.Acquire(); state[j] = HUNGRY; test(j); if (state[j] != EAT) self[j].Wait(); mutex.Release(); // eat mutex.Acquire(); state[j] = THINK; test((j+1)%n); // next test((j+n-1)%n); // prev mutex.Release(); // think } void test(int k) { if ((state[(k+n-1)%n)]!=EAT) && (state[k]==HUNGRY) && (state[(k+1)%n]!=EAT)) { state[k] = EAT; self[k].Signal(); } }

slide-67
SLIDE 67

Chapter 2

67 CMPS 111, UC Santa Cruz

The Sleepy Barber Problem

slide-68
SLIDE 68

Chapter 2

68 CMPS 111, UC Santa Cruz

Code for the Sleepy Barber Problem

void barber(void) { while(TRUE) { // Sleep if no customers customers.down(); // Decrement # of waiting people mutex.down(); waiting -= 1; // Wake up a customer to cut hair barbers.up(); mutex.up(); // Do the haircut cut_hair(); } } #define CHAIRS 5 Semaphore customers=0; Semaphore barbers=0; Semaphore mutex=0; int waiting=0; void customer(void) { mutex.down(); // If there is space in the chairs if (waiting<CHAIRS) { // Another customer is waiting waiting++; // Wake up the barber. This is // saved up, so the barber doesn’t // sleep if a customer is waiting customers.up(); mutex.up(); // Sleep until the barber is ready barbers.down(); get_haircut(); } else { // Chairs full, leave the critical // region mutex.up (); } }