Announcements - PowerPoint PPT Presentation

1 / 49
About This Presentation
Title:

Announcements

Description:

... mach/semaphore.h #include mach/task.h #include mach/mach.h ... number of processes waiting for S to increase. number of processes waiting for S to be 0 ... – PowerPoint PPT presentation

Number of Views:25
Avg rating:3.0/5.0
Slides: 50
Provided by: quinn5
Category:

less

Transcript and Presenter's Notes

Title: Announcements


1
Announcements
2
Cooperating Processes
  • Operating systems allow for the creation and
    concurrent execution of multiple processes
    threads
  • eases program complexity
  • increases efficiency
  • Can they work together? How?
  • Messages?
  • What about shared memory?

3
Problems with concurrent execution
  • Concurrent processes (or threads) often need to
    share data (maintained either in shared memory or
    files) and resources
  • If there is no controlled access to shared data,
    some processes will obtain an inconsistent view
    of this data
  • The action performed by concurrent processes will
    then depend on the order in which their execution
    is interleaved
  • Consider two threads one doing x and the other
    doing x--. How many different values for x?

4
The Critical-Section Problem
  • Consider a system
  • n processes P0, P1, , Pn-1
  • Each process has a critical section
  • changing common values
  • updating tables
  • etc.
  • Access to those variables must be safe
  • mutually exclusive

5
The Critical-Section Problem
  • A solution must satisfy 3 conditions
  • Mutual exclusion
  • Progress
  • Bounded waiting
  • No assumptions can be made about speed
  • Solutions execute some entry code and some exit
    code surrounding critical section.

6
Critical Section Properties
  • Mutual Exclusion
  • At any time, at most one process can be in its
    critical section (CS)
  • Progress
  • Only processes that are not executing in their CS
    can participate in the decision of who will enter
    next in the CS.
  • This selection cannot be postponed indefinitely

7
Critical Section Properties
  • Bounded Waiting
  • After a process has made a request to enter its
    CS, there is a bound on the number of times that
    the other processes are allowed to enter their CS
  • otherwise the process will suffer from starvation
  • Of course there must also be no deadlock

8
pthread_mutex
  • int pthread_mutex_init( pthread_mutex_t
    mutex_lock, const pthread_mutexattr_t
    lock_attr)
  • int pthread_mutex_lock( pthread_mutex_t
    mutex_lock)
  • int pthread_mutex_unlock( pthread_mutex_t
    mutex_lock)
  • int pthread_mutex_trylock( pthread_mutex_t
    mutex_lock)

9
include ltpthread.hgt void find_min(void
list_ptr) pthread_mutex_t minimum_value_lock int
minimum_value, partial_list_size main() minim
um_value MIN_INT pthread_init() pthread_mute
x_init(minimum_value_lock, NULL) /inititaliz
e lists etc, create and join threads/ void
find_min(void list_ptr) int
partial_list_ptr, my_min MIN_INT,
i partial_list_ptr (int )list_ptr for (i
0 i lt partial_list_size i) if
(partial_list_ptri lt my_min) my_min
partial_list_ptri pthread_mutex_lock(minimum_v
alue_lock) if (my_min lt minimum_value) minimum
_value my_min pthread_mutex_unlock(minimum_val
ue_lock) pthread_exit(0)
10
Locking Overhead
  • Serialization points
  • Minimize the size of critical sections
  • Be careful
  • Rather than wait, check if lock is available
  • pthread_mutex_trylock
  • If already locked, will return EBUSY
  • Will require restructuring of code

11
pthread_mutex_trylock
/ Finding k matches in a list / void
find_entries(void start_pointer) / This is
the thread function / struct database_record
next_record int count current_pointer
start_pointer do next_record
find_next_entry(current_pointer) count
output_record(next_record) while (count lt
requested_number_of_records) int
output_record(struct database_record record_ptr)
int count pthread_mutex_lock(output_count_lo
ck) output_count count output_count
pthread_mutex_unlock(output_count_lock) if
(count lt requested_number_of_records)
print_record(record_ptr) return (count)
12
pthread_mutex_trylock
/ rewritten output_record function / int
output_record(struct database_record record_ptr)
int count int lock_status
lock_statuspthread_mutex_trylock(output_count_l
ock) if (lock_status EBUSY)
insert_into_local_list(record_ptr) return(0)
else count output_count output_count
number_on_local_list 1 pthread_mutex_unlock
(output_count_lock) print_records(record_ptr,
local_list, requested_number_of_records -
count) return(count number_on_local_list
1)
13
Cooperation through shared mem.
x
x1 x2 x3 xn
P0
P1
1. Wait until x has a value
1. Wait until x is able to be set
2. Use the value
2. Produce a value
3. Change the value to indicate used
3. Set x to the value
Can we increase the parallelism?
What problems does this entail?
14
The Producer-Consumer Problem
repeat produce an item in nextp
while counter n do no-op bufferin
nextp in (in 1) mod n counter
counter 1 until false
repeat while counter 0 do no-op
nextc bufferout out (out 1) mod n
counter counter -1 consume the item
in nextc until false
Are these correct?
Always?
15
Semaphores
  • Synchronization tool provided by the OS
  • Integer variable that gives us two operations
  • wait(s) while s lt 0 do nothing s s
    - 1
  • signal(s) s s 1
  • Modifications to s are atomic.

16
Semaphores for Critical Sections
Shared semaphore mysem 1
repeat wait(mysem) critical
section signal(mysem) remainder
section until false
Will this work for n processes?
17
Semaphore Implementation
  • How do we wait?
  • spin?
  • sleep? How long? How do we wake up?
  • Solution
  • Let process block itself by placing in waiting
    queue
  • wait call places the process on the queue
  • When a process is blocked, it must be woken up
  • signal process must wake up next process on queue
  • Semaphore
  • struct semaphore int value Queue
    processes

18
Wait
wait(Semaphore s) s.value s.value - 1 if
(s.value lt 0) add this process to
s.L block
19
Signal
signal(Semaphore s) s.value s.value 1 if
(s.value lt 0) remove a process P from
s.L wakeup(P)
20
Details
  • Critical
  • Semaphore operations must be atomic
  • Uniprocessor
  • simply inhibit interrupts (normal user cant)
  • Use TestAndSet instruction
  • Multiprocessor
  • hardware must provide special support or
  • use software solutions

21
Using semaphores
  • Two processes P1 and P2
  • Statements S1 and S2
  • S2 must execute only after S1

22
Consider
P0 wait(S) wait(Q) . .
. signal(S) signal(Q)
P1 wait(Q) wait(S) . .
. signal(Q) signal(S)
Is there anything wrong with this?
23
Semaphores
  • Semaphores can be
  • binary
  • counting
  • Binary
  • integer variable is 0 or 1
  • strictly a mutual exclusion variable
  • pthread_mutex
  • Counting
  • integer variable indicates quantity
  • allows more than one process/thread in at a time

24
Bounded Buffer Problem
x1 x2 x3 xn
P0
P1
25
Bounded Buffer Solution
Shared semaphore empty n, full 0, mutex 1
repeat produce an item in nextp wait(empty) w
ait(mutex) add nextp to the buffer signal(mut
ex) signal(full) until false
repeat wait(full) wait(mutex) remove an
item from buffer place it in nextc signal(mutex
) signal(empty) consume the item in
nextc until false
26
Posix Semaphores
  • Counting semaphores
  • sem_init - creates a unnamed semaphore and
    initializes it
  • int sem_init(sem_t sem, int pshared, unsigned
    int value)
  • sem_open - creates a named semaphore and
    initializes it
  • sem_t sem_open(const char name, int oflag,
  • mode_t mode, unsigned int
    value)
  • sem_wait - performs a wait operation
  • int sem_wait(sem_t sem)
  • int sem_trywait(sem_t sem)
  • int sem_timedwait(sem_t sem, const struct
    timespec abs_timeout)
  • sem_post - performs a signal operation
  • int sem_post(sem_t sem)

27
include ltstdio.hgt include ltstdlib.hgt include
ltpthread.hgt include ltunistd.hgt include
ltsemaphore.hgt void functionC(void ptr) int
counter 0 sem_t sem main() int rc1,
rc2 pthread_t thread1, thread2
sem_init(sem, PTHREAD_PROCESS_PRIVATE, 1) //
Now it is set to one, one person will be able to
access at a time printf("Got semaphore
d\n",sem) / Create independent threads
each of which will execute functionC / if(
(rc1pthread_create( thread1, NULL, functionC,
NULL)) ) printf("Thread creation
failed d\n", rc1) if(
(rc2pthread_create( thread2, NULL, functionC,
NULL)) ) printf("Thread creation
failed d\n", rc2) / Wait till
threads are complete before main continues.
Unless we / / wait we run the risk of
executing an exit which will terminate / /
the process and all threads before the threads
have completed. / pthread_join( thread1,
NULL) pthread_join( thread2, NULL)
sem_close(sem) exit(0)
This works for Linux
void functionC(void ptr) int tmp
sem_wait(sem) tmp counter sleep(1)
tmp counter tmp printf("Counter
value d\n",counter) sem_post(sem)
28
ifdef __APPLE__ include ltmach/semaphore.hgt incl
ude ltmach/task.hgt include ltmach/mach.hgt else in
clude ltsemaphore.hgt endif void qsem_create(void
semStructure, int initialValue) ifdef
__APPLE__ semaphore_create(mach_task_self(),
(semaphore_t )semStructure, SYNC_POLICY_FIFO,
initialValue) else int pshared 0
sem_init((sem_t )semStructure, pshared,
initialValue) endif void qsem_signal(void
semStructure) ifdef __APPLE__
semaphore_signal(((semaphore_t
)semStructure)) else sem_post((sem_t
)semStructure) endif void qsem_wait(void
semStructure) ifdef __APPLE__
semaphore_wait(((semaphore_t )semStructure)) e
lse sem_wait((sem_t )semStructure) endif
void qsem_close(void semStructure) ifdef
__APPLE__ semaphore_destroy(mach_task_self(),
((semaphore_t )semStructure)) else
sem_close((sem_t )semStructure) endif
ifdef __APPLE__ semaphore_t sem else sem_t
sem endif
29
Unix System V Semaphores
  • Are a generalization of the counting semaphores
    (more operations are permitted).
  • A semaphore includes
  • the current value S of the semaphore
  • number of processes waiting for S to increase
  • number of processes waiting for S to be 0
  • System calls
  • semget creates an array of semaphores
  • semctl allows for the initialization of
    semaphores
  • semop performs a list of operations one on each
    semaphore (atomically)

30
Unix Semaphore Code
  • Creation
  • union semun argument
  • key_t key IPC_PRIVATE
  • int flags 0777 IPC_CREAT
  • int semid semget(key, 1, flags)
  • argument.val initialvalue
  • semctl(semid, 0, SETVAL, argument)
  • Destruction
  • int ignored_int
  • union semun ignored
  • semctl(semid, ignored_int, IPC_RMID, ignored)

include ltsys/types.hgt include
ltsys/ipc.hgt include ltsys/sem.hgt void
functionC(void ptr) int counter 0 int
sem define NSEMS 1 define SEMFLAG (IPC_CREAT
0666) union semun int val
/ Value for SETVAL / struct semid_ds
buf / Buffer for IPC_STAT, IPC_SET /
unsigned short array / Array for GETALL,
SETALL / struct seminfo __buf /
Buffer for IPC_INFO (Linux specific) /
31
Unix Semaphores
  • Each operation to be done is specified by a value
    sem_op.
  • Let S be the semaphore value
  • if sem_op gt 0 (signal operation)
  • S is incremented and process awaiting for S to
    increase are awaken
  • if sem_op 0
  • If S0 do nothing
  • if S!0, block the current process on the event
    that S0
  • if sem_op lt 0 (wait operation)
  • if S gt sem_op then S S - sem_op then
    if S lt0 wait

32
Wait and Signal
  • Set up the operations array for 1 semaphore
  • struct sembuf operations1
  • operations0.sem_num 0
  • operations0.sem_flg SEM_UNDO
  • Wait
  • operations0.sem_op -1
  • Signal
  • operations0.sem_op 1
  • Execute the operation on 1 semaphore
  • semop(semid, operations, 1)

33
Semaphores Interrupts
  • Semaphore operations may be interrupted
  • Will not be restarted
  • Semop will return -1

int sem_wait(int semid) struct sembuf
operations1 int retval
operations0.sem_num 0 operations0.sem_o
p -1 operations0.sem_flg
SEM_UNDO while ((retval semop(semid,
operations, 1)) -1) if (errno !
EINTR) fprintf(stderr,"sem_wait error
d\n", errno) exit(4) return
retval
34
Unix Semaphores
  • Operating System level data structure
  • Can be shared among processes
  • Identified by a key and an ID
  • List semaphores
  • ipcs
  • Remove zombie semaphores
  • ipcrm -s semid

35
Classical Synchronization Problems
  • Counting semaphores from binary semaphores
  • Bounded Buffer
  • Shared buffer between producer and consumer
  • Readers and Writers
  • data object shared between many
  • some read only
  • some write only
  • Dining Philosophers
  • n processes
  • p resources

36
Binary to Counting Semaphores
  • Can you create a counting semaphore from binary
    semaphores?
  • Needed
  • Integer count
  • Operations on the count must be atomic
  • Must block processes appropriately
  • How many binary semaphores are needed?
  • Can you do it with just one?

37
Binary to Counting Semaphores
Typedef struct qsem pthread_mutex_t s int
value void wait(qsem_t q) pthread_mutex_l
ock(q-gts) q-gtvalue-- if (value lt 0)
// I need to block..... how? pthread_mutex_unl
ock(q-gts)
void signal(qsem_t q) pthread_mutex_loc
k(q-gts) q-gtvalue if (value lt 0) //
I need to wake someone // .....
how? pthread_mutex_unlock(q-gts)
38
Binary to Counting Semaphores
void qsem_create(qsem_t q, int initialvalue)
pthread_mutex_init((q-gts1), NULL)
pthread_mutex_init((q-gts2), NULL) // We
must initialize s1 to 1(default) // and s2
to 0 (we must lock it) pthread_mutex_lock((q
-gts2)) q-gtvalue initialvalue void
signal(qsem_t q) pthread_mutex_lock((q-gts1))
q-gtvalue if (value lt 0)
pthread_mutex_unlock((q-gts2)) else
pthread_mutex_unlock((q-gts1))
typedef struct qsem pthread_mutex_t
s1 pthread_mutex_t s2 int value void
wait(qsem_t q) pthread_mutex_lock((q-gts1))
q-gtvalue-- if (value lt 0)
pthread_mutex_unlock((q-gts1))
pthread_mutex_lock((q-gts2)) pthread_mutex_u
nlock((q-gts1))
39
Bounded Buffer Problem
x1 x2 x3 xn
P0
P1
40
Bounded Buffer Solution?
repeat produce an item in nextp
while counter n do no-op bufferin
nextp in (in 1) mod n counter
counter 1 until false
repeat while counter 0 do no-op
nextc bufferout out (out 1) mod n
counter counter -1 consume the item
in nextc until false
41
Bounded Buffer Solution
Shared semaphore empty n, full 0,
producer_mutex 1, consumer_mutex 1
repeat produce an item in nextp wait(empty) w
ait(producer_mutex) add nextp to the
buffer only modify in signal(producer_mutex)
signal(full) until false
repeat wait(full) wait(consumer_mutex) remov
e an item from buffer place it in nextc only
modify out signal(consumer_mutex) signal(empty
) consume the item in nextc until false
Note We dont need counter any more. Why?
42
The Dining Philosophers Problem
  • 5 philosophers who only eat and think
  • each need to use 2 forks for eating
  • we have only 5 forks
  • Illustrates the difficulty of allocating
    resources among processes/threads without
    deadlock and starvation

43
The Dining Philosophers Problem
  • Each philosopher is a process
  • One semaphore per fork
  • fork array0..4 of semaphores
  • Initialization forki.count1 for i0..4
  • A first attempt

Process Pi repeat think wait(forki)
wait(forki1 mod 5) eat signal(forki1 mod
5) signal(forki) forever
  • Deadlock if each philosopher starts by picking
    left fork!

44
The Dining Philosophers Problem
  • A solution admit only 4 philosophers at a time
    that tries to eat
  • Then 1 philosopher can always eat when the other
    3 are holding 1 fork
  • Introduce semaphore T that limits at 4 the numb.
    of philosophers sitting at the table
  • Initialize T.count4

Process Pi repeat think wait(T)
wait(forki) wait(forki1 mod 5) eat
signal(forki1 mod 5) signal(forki)
signal(T) forever
45
Other solutions
  • A philosopher may only pick up forks in pairs
  • must allocate all resources at once
  • Asymmetric solution
  • odd philosophers select left then right
  • even philosophers select right then left
  • All solutions must not starve a philosopher

46
Readers and Writers Problem
  • Data object is shared
  • many readers
  • many writers
  • Many can read at the same time
  • Only one writer at a time
  • no reading while writing
  • Many different varieties
  • reader priority
  • writer priority

47
Readers - Writers (priority?)
Shared Semaphore mutex1, wrt 1 Shared
integer readcount 0
wait(mutex) readcount readcount 1 if
(readcount 1) wait(wrt) signal(mutex) read
the data wait(mutex) readcount readcount -
1 if (readcount 0) signal(wrt) signal(mutex)

wait(wrt) write to the data object signal(wrt)
48
Readers Writers (priority?)
outerQ, rsem, rmutex, wmutex, wsem 1
wait (outerQ) wait (rsem) wait
(rmutex) readcnt if (readcnt 1) wait
(wsem) signal(rmutex) signal
(rsem) signal (outerQ) READ wait (rmutex)
readcnt-- if (readcnt 0) signal
(wsem) signal (rmutex)
wait (wsem) writecnt if (writecnt
1) wait (rsem) signal (wsem) wait
(wmutex) WRITE signal (wmutex) wait (wsem)
writecnt-- if (writecnt 0) signal
(rsem) signal (wsem)
49
The Barbershop
Barber chairs
Cashier
Entrance
Standing room area
Exit
Sofa
Write a Comment
User Comments (0)
About PowerShow.com