15 Sem Mutex
15 Sem Mutex
Semaphores
Counting Semaphores
Permit a limited number of threads to execute a
section of the code
Binary Semaphores - Mutexes
Permit only one thread to execute a section of
the code
Condition Variables
Communicate information about the state of
shared data
Data type
Semaphore is a variable of type sem_t
Include <semaphore.h>
Atomic Operations
int sem_init(sem_t *sem, int pshared,
unsigned value);
int sem_destroy(sem_t *sem);
int sem_post(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_wait(sem_t *sem);
Copyright ©: University of Illinois CS 241 Staff 4
Unnamed Semaphores
#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned
value);
Initialize an unnamed semaphore
Returns You cannot make a copy of a
0 on success semaphore variable!!!
-1 on failure, sets errno
Parameters
sem:
Target semaphore
pshared:
0: only threads of the creating process can use the semaphore
Non-0: other processes can use the semaphore
value:
Initial value of the semaphore
Copyright ©: University of Illinois CS 241 Staff 5
Sharing Semaphores
Sharing semaphores between threads
within a process is easy, use pshared==0
A non-zero pshared allows any process
that can access the semaphore to use it
Places the semaphore in the global (OS)
environment
Forking a process creates copies of any
semaphore it has
Note: unnamed semaphores are not shared across
unrelated processes
On failure
sem_init returns -1 and sets errno
errno cause
EINVAL Value > sem_value_max
ENOSPC Resources exhausted
EPERM Insufficient privileges
sem_t semA;
if (sem_init(&semA, 0, 1) == -1)
perror(“Failed to initialize semaphore semA”);
Copyright ©: University of Illinois CS 241 Staff 7
Semaphore Operations
#include <semaphore.h>
int sem_destroy(sem_t *sem);
Destroy an semaphore
Returns
0 on success
-1 on failure, sets errno
Parameters
sem:
Target semaphore
Notes
Can destroy a sem_t only once
Destroying a destroyed semaphore gives undefined results
Destroying a semaphore on which a thread is blocked gives undefined
results
int incshared() {
while (sem_wait(&balance_sem) == -1)
if (errno != EINTR)
return -1;
balance++;
return sem_post(&balance_sem);
}
Copyright ©: University of Illinois CS 241 Staff 13
Example: bank balance
#include <errno.h>
#include <semaphore.h>
Parameters
mutex: Target mutex
attr:
NULL: the default mutex attributes are used
Non-NULL: initializes with specified attributes
Copyright ©: University of Illinois CS 241 Staff 19
Creating a mutex
Default attributes
Use PTHREAD_MUTEX_INITIALIZER
Statically allocated
Equivalent to dynamic initialization by a call
to pthread_mutex_init() with parameter
attr specified as NULL
No error checks are performed
pthread_mutex_unlock (&my_lock);
for (j=0; j<50000000; j++);
}
} Copyright ©: University of Illinois CS 241 Staff 23
Condition Variables
Waiting
Block on a condition variable.
Called with mutex locked by the calling thread
Atomically release mutex and cause the calling
thread to block on the condition variable
On return, mutex is locked again
int pthread_cond_wait(pthread_cond_t *cond,
pthread_mutex_t *mutex);
int pthread_cond_timedwait(pthread_cond_t *cond,
pthread_mutex_t *mutex, const struct timespec
*abstime);
Copyright ©: University of Illinois CS 241 Staff 27
Using a Condition Variable
Signaling
int pthread_cond_signal(pthread_cond_t *cond);
unblocks at least one of the blocked threads
int pthread_cond_broadcast(pthread_cond_t *cond);
unblocks all of the blocked threads
pthread_cond_wait(&condvar, &mutex);
/* go to sleep – recheck
pred on awakening */
}
pthread_mutex_unlock(&mutex); /* unlock mutex */
void *producer(void *) {
pthread_mutex_lock(&data_mutex);
<Produce data>
<Insert data into queue;>
data_avail=1;
pthread_mutex_unlock(&data_mutex);
}
pthread_mutex_lock(&data_mutex);
Busy Waiting!
<Extract data from queue;>
if (queue is empty)
data_avail = 0;
pthread_mutex_unlock(&data_mutex);
<Consume Data>
}
void *producer(void *) {
pthread_mutex_lock(&data_mutex);
<Produce data>
<Insert data into queue;>
data_avail = 1;
pthread_cond_signal(&data_cond);
pthread_mutex_unlock(&data_mutex);
}
Master thread
Spawns a number of concurrent slaves
Waits until all of the slaves have finished to exit
Tracks current number of slaves executing
A mutex is associated with count and a
condition variable with the mutex
#define NO_OF_PROCS 4
SharedType_ptr shared_data;