0% found this document useful (0 votes)
132 views

CS241 System Programming: Discussion Section 4 Feb 13 - Feb 16

This document summarizes topics related to system programming including synchronization techniques using condition variables and reader-writer problems. It provides code examples for implementing a producer-consumer problem using both condition variables and semaphores. It also discusses CPU scheduling algorithms like priority scheduling and provides an example of priority scheduling in action.

Uploaded by

Gaurav
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
132 views

CS241 System Programming: Discussion Section 4 Feb 13 - Feb 16

This document summarizes topics related to system programming including synchronization techniques using condition variables and reader-writer problems. It provides code examples for implementing a producer-consumer problem using both condition variables and semaphores. It also discusses CPU scheduling algorithms like priority scheduling and provides an example of priority scheduling in action.

Uploaded by

Gaurav
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 31

CS241

System Programming
Discussion Section 4
Feb 13 – Feb 16
Outline
z Synchronization
z Condition Variables
z Producer-Consumer Problem
z Reader-Writer Problem

z CPU Scheduling
z Metrics
z Examples
Review
z What is wrong with the following code fragment
in multi-threaded environment? How would you
modify it?
static int count;

void increment(void) {
count++;
}

void decrement(void) {
count--;
}

int getcount() {
return count;
}
Review
z Thread-Safe version (using mutex)
static int count = 0;
static pthread_mutex_t countlock = PTHREAD_MUTEX_INITIALIZER;

int increment(void) { /* decrement() similar */


int error;
if (error = pthread_mutex_lock(&countlock))
return error;
count++;
return pthread_mutex_unlock(&countlock);
}
int getcount(int *countp) {
int error;
if (error = pthread_mutex_lock(&countlock))
return error;
*countp = count;
return pthread_mutex_unlock(&countlock);
}
Condition Variables
z Allows explicit event notification
z Implements a monitor along with a mutex

z #include <pthread.h>
z Type: pthread_cond_t
z Two main operations
z Wait: pthread_cond_wait
z Signal: pthread_cond_signal
Example
z Waiting for x==y condition
pthread_mutex_lock(&m);
while (x != y)
pthread_cond_wait(&v, &m);
/* modify x or y if necessary */
pthread_mutex_unlock(&m);

z Notifying the waiting thread that it has incremented x


pthread_mutex_lock(&m);
x++;
pthread_cond_signal(&v);
pthread_mutex_unlock(&m);
Creating / Destroying CVs
z Creating a condition variable
z Standard Initializer
int pthread_cond_init(pthread_cond_t *restrict cond,
const pthread_condattr_t *restrict attr);

z Static Initializer
pthread_cont_t cond = PTHREAD_COND_INITIALIZER;

z Destroying a condition variable


int pthread_cond_destroy(pthread_cond_t *cond);

z Returns 0 if successful, nonzero error code if


unsuccessful
Waiting on CVs
int pthread_cond_wait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex);

z Called with a mutex lock held

z Internals
z Causes the thread to release the mutex
z Sleeps until signaled
z Reacquires the lock when waken up

z Variation: pthread_cond_timedwait
Signaling on CVs
z Signal
z Wakes up one waiting thread
int pthread_cond_signal(pthread_cond_t *cond);

z Broadcast
z Wakes up all waiting threads
int pthread_cond_broadcast(pthread_cond_t *cond);
Example
z Thread-safe Barrier (Program 13.13)
int waitbarrier(void) { /* wait at the barrier until all n threads arrive */
int berror = 0;
int error;

if (error = pthread_mutex_lock(&bmutex)) /* couldn't lock, give up */


return error;
if (limit <= 0) { /* make sure barrier initialized (limit = #threads) */
pthread_mutex_unlock(&bmutex);
return EINVAL;
}
count++;
while ((count < limit) && !berror)
berror = pthread_cond_wait(&bcond, &bmutex);
if (!berror)
berror = pthread_cond_broadcast(&bcond); /* wake up everyone */
error = pthread_mutex_unlock(&bmutex);
if (berror)
return berror;
return error;
}
Producer-Consumer Problem
z Given variables
static buffer_t buffer[BUFSIZE];
static pthread_mutex_t bufferlock = PTHREAD_MUTEX_INITIALIZER;
static int bufin = 0;
static int bufout = 0;
static pthread_cond_t items = PTHREAD_COND_INITIALIZER;
static pthread_cond_t slots = PTHREAD_COND_INITIALIZER;
static int totalitems = 0;

z Implement the following functions using CVs


z int getitem(buffer_t *itemp)
z removes item from butter and put in *itemp
z int putitem(buffer_t item)
z Inserts item in the buffer
Implementation using CVs
int getitem(buffer_t *itemp) {
int error;
if (error = pthread_mutex_lock(&bufferlock))
return error;
while ((totalitems <= 0) && !error)
error = pthread_cond_wait (&items, &bufferlock);
if (error) {
pthread_mutex_unlock(&bufferlock);
return error;
}
*itemp = buffer[bufout];
bufout = (bufout + 1) % BUFSIZE;
totalitems--;
if (error = pthread_cond_signal(&slots)) {
pthread_mutex_unlock(&bufferlock);
return error;
}
return pthread_mutex_unlock(&bufferlock);
}
Implementation using CVs
int putitem(buffer_t item) {
int error;
if (error = pthread_mutex_lock(&bufferlock))
return error;
while ((totalitems >= BUFSIZE) && !error)
error = pthread_cond_wait (&slots, &bufferlock);
if (error) {
pthread_mutex_unlock(&bufferlock);
return error;
}
buffer[bufin] = item;
bufin = (bufin + 1) % BUFSIZE;
totalitems++;
if (error = pthread_cond_signal(&items)) {
pthread_mutex_unlock(&bufferlock);
return error;
}
return pthread_mutex_unlock(&bufferlock);
}
Producer-Consumer Problem
z Given variables
static buffer_t buffer[BUFSIZE];
static pthread_mutex_t bufferlock = PTHREAD_MUTEX_INITIALIZER;
static int bufin = 0;
static int bufout = 0;
static sem_t semitems;
static sem_t semslots;

z Implement the following functions using


semaphores
z int getitem(buffer_t *itemp)
z removes item from butter and put in *itemp
z int putitem(buffer_t item)
z Inserts item in the buffer
Implementation using Semaphores
int getitem(buffer_t *itemp) {
int error;
while (((error = sem_wait(&semitems)) == -1) && (errno == EINTR)) ;
if (error)
return errno;
if (error = pthread_mutex_lock(&bufferlock))
return error;
*itemp = buffer[bufout];
bufout = (bufout + 1) % BUFSIZE;
if (error = pthread_mutex_unlock(&bufferlock))
return error;
if (sem_post(&semslots) == -1)
return errno;
return 0;
}
Implementation using Semaphores
int putitem(buffer_t item) {
int error;
while (((error = sem_wait(&semslots)) == -1) && (errno == EINTR)) ;
if (error)
return errno;
if (error = pthread_mutex_lock(&bufferlock))
return error;
buffer[bufin] = item;
bufin = (bufin + 1) % BUFSIZE;
if (error = pthread_mutex_unlock(&bufferlock))
return error;
if (sem_post(&semitems) == -1)
return errno;
return 0;
}
Reader-Writer Problem
z Two types of access
z Read: may be shared
z Write: must be exclusive

z Reader-Writer Synchronization
z Strong Reader Synchronization
z Preference to readers (e.g. a library database)
z Strong Writer Synchronization
z Preference to writers (e.g. an airline reservation system)

z POSIX provides read-write locks


Read-Write Locks
z Allows multiple readers to acquire a lock
z When a writer does not hold the lock

z #include <pthread.h>
z Type: pthread_rwlock_t
z Three main operations
z Read Lock: pthread_rwlock_rdlock
z Write Lock: pthread_rwlock_wrlock
z Unlock: pthread_rwlock_unlock
Creating / Destroying rwlock
z Creating a read-write lock
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,
const pthread_rwlockattr_t *restrict attr);

z Destroying a read-write lock


int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

z Returns 0 if successful, nonzero error code if


unsuccessful
Acquiring / Releasing rwlock
z Acquiring a read-write lock
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);

z Releasing a read-write lock


int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

z Returns 0 if successful, nonzero error code if


unsuccessful

z Implementations may favor writers over readers to


avoid writer starvation.
CPU Scheduling
z Decides which thread should be in the
running state

z Algorithms
z First-Come First-Serve (FCFS)
z Shortest Job First (SJF)
z Round Robin (RR)
z Priority
CPU Scheduling
z Preemptive vs Non-preemptive
z Non-Preemptive: The running thread keeps CPU until it
voluntarily gives it up
z Preemptive: The running thread can be forced to give up
CPU by another thread

z Metrics
z Waiting Time
z Total amount time that a thread waits
z Turnaround Time
z (Thread finish time – thread entry time)
A Simple Example (Priority)
Process Duration Priority # Arrival Time
P1 6 4 0
P2 8 1 0
P3 7 3 0
P4 3 2 0

Initial Condition
A Simple Example (Priority)
Process Duration Priority # Arrival Time
P1 6 4 0
P2 8 1 0
P3 7 3 0
P4 3 2 0

After 8 seconds
A Simple Example (Priority)
Process Duration Priority # Arrival Time
P1 6 4 0
P2 8 1 0
P3 7 3 0
P4 3 2 0

After 11 seconds
A Simple Example (Priority)
Process Duration Priority # Arrival Time
P1 6 4 0
P2 8 1 0
P3 7 3 0
P4 3 2 0

After 18 seconds
A Simple Example (Priority)
Process Duration Priority # Arrival Time
P1 6 4 0
P2 8 1 0
P3 7 3 0
P4 3 2 0

After 24 seconds
A Simple Example (Priority)
Process Duration Priority # Arrival Time
P1 6 4 0
P2 8 1 0
P3 7 3 0
P4 3 2 0

P2 (8) P4 (3) P3 (7) P1 (6)

0 8 11 18 24
P2 waiting time: 0 The average waiting time (AWT):
P4 waiting time: 8
P3 waiting time: 11 (0+8+11+18)/4 = 9.25
P1 waiting time: 18
A Simple Example (Priority)
Process Duration Priority # Arrival Time
P1 6 4 0
P2 8 1 0
P3 7 3 0
P4 3 2 0

P2 (8) P4 (3) P3 (7) P1 (6)

0 8 11 18 24
P2 turnaround time: 8 The average turnaround time (ATT):
P4 turnaround time: 11
P3 turnaround time: 18 (8+11+18+24)/4 = 15.25
P1 turnaround time: 24
POSIX Scheduling
z #include <sched.h>

z Defines sched_param structure

z Defines 4 scheduling policies


z SCHED_FIFO
z SCHED_RR
z SCHED_SPORADIC
z SCHED_OTHER

z Defines several scheduling functions. For example,


z int sched_yield(void);
Summary
z Synchronization
z Condition Variables: pthread_cond_*
z Producer-Consumer Problem
z Using condition variables
z Using semaphores
z Reader-Writer Problem: pthread_rwlock_*

z CPU Scheduling
z Metrics
z Waiting Time, Turnaround Time
z Examples

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy