+ All Categories
Home > Documents > CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization...

CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization...

Date post: 08-Jul-2020
Category:
Upload: others
View: 2 times
Download: 0 times
Share this document with a friend
21
CS 5460: Operating Systems CS5460: Operating Systems Lecture 10: Semaphores and Classical Synch Problems (Chapter 6)
Transcript
Page 1: CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization So Far… Basically everything we’ve covered so far is about mutual exclusion,

CS 5460: Operating Systems

CS5460: Operating Systems Lecture 10:

Semaphores and Classical Synch Problems

(Chapter 6)

Page 2: CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization So Far… Basically everything we’ve covered so far is about mutual exclusion,

CS 5460: Operating Systems

Synchronization So Far…   Race conditions   Mutual exclusion   Data races   Requirements for correct synchronization:

–  Mutual exclusion –  Progress –  Bounded wait

  Arguing correctness for critical sections   Basic solutions to the critical section problem:

–  2-process solution à Peterson, Dekker –  N-process solution à Bakery Algorithm –  Spinlocks and blocking locks based on HW primitives

Page 3: CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization So Far… Basically everything we’ve covered so far is about mutual exclusion,

CS 5460: Operating Systems

Synchronization So Far…   Basically everything we’ve covered so far is about

mutual exclusion, a.k.a. locking   But there are plenty of synchronization problems

that require more than just locking   For example:

–  How do we make a bank account processing thread wait until the account balance is positive?

–  How do we make a producer thread wait for a free buffer, and a consumer thread wait for a full buffer?

–  How can we implement a “lock” where many reader threads can execute inside the critical section at once, but only one writer?

  It can be hard to do jobs like these using just locks   Today we’ll look at higher-level sync. primitives

Page 4: CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization So Far… Basically everything we’ve covered so far is about mutual exclusion,

CS 5460: Operating Systems

Semaphores   A semaphore is a counter that processes or threads

can manipulate atomically   Operations on a semaphore:

–  P() or down() or wait() : wait until counter > 0, then atomically decrement it

–  V() or up() or signal() or post(): atomically increment counter

  Counter generally represents the number of available resources

–  Never negative

  A semaphore whose counter is always 0 or 1 is called a binary semaphore

–  This is just a lock

Page 5: CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization So Far… Basically everything we’ve covered so far is about mutual exclusion,

CS 5460: Operating Systems

Implementing Semaphores Semaphore::P (T:Thread) {

disable interrupts;

while (counter <= 0) {

add T to Q;

T à Sleep();

}

counter--;

enable interrupts;

}

Semaphore::V () {

disable interrupts;

counter++;

if (Q not empty) {

remove T from Q;

put T on readyQ;

}

enable interrupts;

}

Class Semaphore {

public:

void P();

void V();

private:

int counter;

Queue Q;

}

Semaphore::Semaphore (int init) {

counter ß init;

Q ß 0; // Queue empty

}

Page 6: CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization So Far… Basically everything we’ve covered so far is about mutual exclusion,

CS 5460: Operating Systems

Semaphores in Pthreads   Pthreads provides semaphores for you   Main operations:

–  sem_init() –  sem_post() –  sem_wait() –  sem_destroy()

  But also: –  sem_getvalue() –  sem_open() –  sem_close() –  sem_unlink()

Page 7: CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization So Far… Basically everything we’ve covered so far is about mutual exclusion,

CS 5460: Operating Systems

Bounded Buffer Problem   Collection of “producer” and “consumer” threads   Fixed-size (e.g., N-entry) shared buffer   Producers generate “work” and add to buffer   Consumers remove “work” from buffer and do it   Need to handle:

–  Concurrent threads adding/removing from buffer –  Buffer overflow and underflow

Page 8: CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization So Far… Basically everything we’ve covered so far is about mutual exclusion,

CS 5460: Operating Systems

Bounded Buffer Solution BBuffer:AddItem( ) {

entry:

PUT : // Put item in free slot

exit :

}

BBuffer:GetItem( ) {

entry:

GET : // Get item from buffer

exit :

}

  Let’s solve this interactively –  Hint: Use provided semaphores –  What do they mean?

Class BBuffer{

private: semaphore mutex;

semaphore empty;

semaphore full;

int buffer[N];

public: void AddItem( );

void GetItem( );

}

BBuffer::BBuffer ( ) {

mutex = l;

full = 0;

empty = N;

}

Page 9: CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization So Far… Basically everything we’ve covered so far is about mutual exclusion,

CS 5460: Operating Systems

Bounded Buffer Solution BBuffer:AddItem( ) {

entry: P(empty);

P(mutex);

PUT : // Put item in free slot

exit : V(mutex);

V(full);

}

BBuffer:GetItem( ) {

entry: P(full);

P(mutex);

GET : // Get item from buffer

exit : V(mutex);

V(empty);

}

  Let’s solve this interactively –  Hint: Use provided semaphores –  What do they mean?

Class BBuffer{

private: semaphore mutex;

semaphore empty;

semaphore full;

int buffer[N];

public: void AddItem( );

void GetItem( );

}

BBuffer::BBuffer ( ) {

mutex = l;

full = 0;

empty = N;

}

Page 10: CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization So Far… Basically everything we’ve covered so far is about mutual exclusion,

CS 5460: Operating Systems

Readers-Writers Problem

  Problem: Shared resource that is “read mostly” –  Enforcing strict mutual exclusion may be unacceptable –  Want to allow arbitrary number of “readers” concurrently –  Only want to allow “writer” if nobody else reading or writing

  Allowing multiple readers à important optimization –  Many applications have far more readers than writers –  Another example of enabling concurrency when possible –  All real OS kernels support and use reader/writer locks

  How do you know you need a reader / writer lock?

Page 11: CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization So Far… Basically everything we’ve covered so far is about mutual exclusion,

CS 5460: Operating Systems

Readers-Writers Problem ReadWrite::Read() {

entry:

READ: /* Read data */

exit:

}

ReadWrite::Write() {

entry:

WRITE: /* Write data */

exit:

}

class ReadWrite {

public: void Read(), Write();

private: semaphore mutex, writer;

int readers;

}

ReadWrite::ReadWrite {

mutex = writer = 1;

readers = 0;

}

Page 12: CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization So Far… Basically everything we’ve covered so far is about mutual exclusion,

CS 5460: Operating Systems

Readers-Writers v1 ReadWrite::Read() {

entry: P(mutex);

READ: /* Read data */

exit: V(mutex);

}

ReadWrite::Write() {

entry: P(mutex);

WRITE: /* Write data */

exit: V(mutex);

}

class ReadWrite {

public: void Read(), Write();

private: semaphore mutex;

}

ReadWrite::ReadWrite {

mutex = 1;

}

Poor concurrency

Page 13: CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization So Far… Basically everything we’ve covered so far is about mutual exclusion,

CS 5460: Operating Systems

Readers-Writers v2 ReadWrite::Read() {

entry: P(mutex);

if ((++readers) == 1) // 1st

P(writer);

V(mutex);

READ: /* Read data */

exit: P(mutex);

if ((--readers) == 0) // Last

V(writer);

V(mutex);

}

ReadWrite::Write() {

entry: P(writer);

WRITE: /* Write data */

exit: V(writer);

}

  Who does this favor? –  Read() –  | Write() –  | X Read() –  (Done) X | –  … X

class ReadWrite {

public: void Read(), Write();

private: semaphore mutex, writer;

int readers;

}

ReadWrite::ReadWrite {

mutex = writer = 1;

readers = 0;

} Readers preferred – why?

Page 14: CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization So Far… Basically everything we’ve covered so far is about mutual exclusion,

CS 5460: Operating Systems

Readers-Writers v3 ReadWrite::Read() {

entry: P(rw);

READ: /* Read data */

exit: V(rw);

}

ReadWrite::Write() {

entry: for (i=1..MAX_READERS) {

P(rw);

}

WRITE: /* Write data */

exit: for (i=1..MAX_READERS) {

V(rw);

}

}

class ReadWrite {

public: void Read(), Write();

private: semaphore rw;

}

ReadWrite::ReadWrite {

rw = MAX_READERS;

}

Problem?

Page 15: CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization So Far… Basically everything we’ve covered so far is about mutual exclusion,

CS 5460: Operating Systems

Readers-Writers v4 ReadWrite::Read() {

entry: P(rw);

READ: /* Read data */

exit: V(rw);

}

ReadWrite::Write() {

entry: P(mutex);

for (i=1..MAX_READERS)

P(rw);

WRITE: /* Write data */

exit: for (i=1..MAX_READERS)

V(rw);

V(mutex);

}

class ReadWrite {

public: void Read(), Write();

private: semaphore rw, mutex;

}

ReadWrite::ReadWrite {

rw = MAX_READERS;

mutex = 1;

}

Page 16: CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization So Far… Basically everything we’ve covered so far is about mutual exclusion,

CS 5460: Operating Systems

Condition Variable   Queue of threads waiting on some “event” inside of

a critical section   A condition variable is always paired with a lock   Operations:

–  Wait(): »  Atomically release lock and go to sleep »  When thread wakes up, it reacquires the lock

–  Signal(): »  Wake up thread waiting on event à no-op if nobody is waiting

–  Broadcast(): »  Wake up all threads waiting on event à no-op if nobody is waiting

Page 17: CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization So Far… Basically everything we’ve covered so far is about mutual exclusion,

CS 5460: Operating Systems

Monitors

  Semantics: Only one thread in “object” at a time

–  Higher level than locks/sems –  Cannot “forget” to lock/unlock –  Can ensure mutual exclusion

across multiple code segments –  Protects private data of monitor

  Java usage –  All data must be private –  All private methods synchronized

Class ReaderWriter {

private int readcnt = 0;

private int writecnt = 0;

private synchronized ReadStart(){

while (writecnt > 0) Wait();

readcnt++;

}

private synchronized ReadDone(){

if (--readcnt == 0) Notify();

}

public … SomeReadMethod() {

ReadStart();

// Read private data;

ReadDone();

}

Page 18: CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization So Far… Basically everything we’ve covered so far is about mutual exclusion,

CS 5460: Operating Systems

Thread Barriers

  Semantics: “N” threads block at barrier until all arrive

  Usage: Synchronize between “phases” of parallel programs

–  e.g., divide array among threads that use “neighboring” data

–  Need neighbors roughly synched

  No mutual exclusion

  Goal: Maximize throughput –  Minimize barrier overhead

int A[N][N];

int mypid;

Barrier B;

InitBarrier(&B, N);

for (j=0; j < loopcnt; j++){

for (i=0; i < N; i++) {

/* Update my part of A */

A[mypid][i] = …;

}

/* Wait for other threads */

BarrierWait(&B);

}

Page 19: CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization So Far… Basically everything we’ve covered so far is about mutual exclusion,

CS 5460: Operating Systems

Barrier Implementation (simplified) Class Barrier {

public: Wait();

private: semaphore mutex;

int limit, count;

}

Barrier::Barrier(b:int) {

mutex = 1; limit = b;

count = 0;

}

Barrier::Wait() {

P(mutex); count++; V(mutex);

while (count != limit);

}

  Simple implementation: –  Atomically increment count of

threads waiting at barrier –  Spin on global count until it

reaches limit

  What performance problems? –  Spinning is inefficient –  To increment shared count, need

to acquire/release mutex –  Every time count is incremented,

need to invalidate copies being spun on (multiprocessor

Page 20: CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization So Far… Basically everything we’ve covered so far is about mutual exclusion,

CS 5460: Operating Systems

Blocking Barrier Implementation

Class Barrier {

public: Wait();

private: semaphore mutex;

int limit, count;

condition cond;

}

Barrier::Barrier(b:int) {

mutex = 1; limit = b;

}

Barrier::Wait() {

P(mutex);

count++;

if (count == limit) {

count = 0;

broadcast (cond);

} else {

wait (cond, mutex);

}

V(mutex);

}

Page 21: CS5460: Operating Systemscs5460/slides/Lecture10.pdf · CS 5460: Operating Systems Synchronization So Far… Basically everything we’ve covered so far is about mutual exclusion,

CS 5460: Operating Systems

Questions?


Recommended