Monitors con’t / Reader/Writer Locks / Deadlock (start) 1
Changelog 2 October: simulation of reader/writer lock: condition for signaling guarentee order 2 October: monitors with semaphore: clarify on slide that this is to 2 October: monitor exercise: make entire code fjt on slide 2 October: rwlock exercise solution?: remove extraneous writer IDs 2 October: rwlock exercise solution?: add “if (need to wait)” writer should have been waiting_writers != 0 decremented too early Changes made in this version not seen in fjrst lecture: 2 October: simulation of reader/writer lock: correct readers being writer should have been waiting_writers != 0 2 October: writer-priority reader/writer lock: condition for signaling bufger.size = capacity - 1 doesn’t work correctly 2 October: bounded bufger producer/consumer: signalling only when been bufger.full, not !bufger.full 2 October: bounded bufger producer/consumer: condition should have 1
last time barriers — wait for everyone else counting semaphores track number of something wait if not any monitors: mutex + condition variables condition variable: wait and signal/broadcast pattern: loop of waiting (spurious wakeup) associated mutex lock: check if need to wait safely producer/consumer solution with semaphores/monitors producer: add to queue, wait if full consumer: remove from queue, wait if empty 2
life HW life HW is out checkpoint (Friday): use POSIX barriers fjnal (week from Friday): write your own barriers questions? 3
unbounded bufger producer/consumer waiting for Produce() …unlock/start wait …empty? yes …lock Consume() Thread 3 Thread 2 Thread 1 data_ready return Consume() …unlock …dequeue …empty? no lock …unlock stop wait …signal …enqueue …lock Produce() …lock …enqueue …empty? yes data_ready not done by pthreads, Java, … called “Hoare scheduling” signalled thread gets lock next alternate design: gaurenteed to hold lock next in pthreads: signalled thread not lock waiting for lock waiting for waiting for …signal …unlock/start wait …empty? yes return …lock …unlock …dequeue …empty? no lock …unlock stop wait …unlock/start wait …lock pthread_mutex_t lock; pthread_cond_wait(&data_ready, &lock); simulatenously en/dequeue? otherwise: what if two threads without acquiring lock rule: never touch buffer } return item; pthread_mutex_unlock(&lock); item = buffer.dequeue(); } while (buffer.empty()) { (both reallocate array?) pthread_mutex_lock(&lock); Consume() { } pthread_mutex_unlock(&lock); pthread_cond_signal(&data_ready); buffer.enqueue(item); pthread_mutex_lock(&lock); Produce(item) { UnboundedQueue buffer; pthread_cond_t data_ready; (both use same array/linked list entry?) check if empty Consume() …enqueue Thread 2 Thread 1 return …unlock …dequeue …empty? no …lock Consume() …unlock …signal …lock if so, dequeue Produce() Thread 2 Thread 1 2+ iterations: spurious wakeup or …? 1 iteration: Produce() signalled, probably 0 iterations: Produce() called before Consume() if any are waiting wake one Consume thread other threads can not dequeue here okay because have lock 4
unbounded bufger producer/consumer waiting for Produce() …unlock/start wait …empty? yes …lock Consume() Thread 3 Thread 2 Thread 1 data_ready return Consume() …unlock …dequeue …empty? no lock …unlock stop wait …signal …enqueue …lock Produce() …lock …enqueue …empty? yes data_ready not done by pthreads, Java, … called “Hoare scheduling” signalled thread gets lock next alternate design: gaurenteed to hold lock next in pthreads: signalled thread not lock waiting for lock waiting for waiting for …signal …unlock/start wait …empty? yes return …lock …unlock …dequeue …empty? no lock …unlock stop wait …unlock/start wait …lock pthread_mutex_t lock; pthread_cond_wait(&data_ready, &lock); simulatenously en/dequeue? otherwise: what if two threads without acquiring lock rule: never touch buffer } return item; pthread_mutex_unlock(&lock); item = buffer.dequeue(); } while (buffer.empty()) { (both reallocate array?) pthread_mutex_lock(&lock); Consume() { } pthread_mutex_unlock(&lock); pthread_cond_signal(&data_ready); buffer.enqueue(item); pthread_mutex_lock(&lock); Produce(item) { UnboundedQueue buffer; pthread_cond_t data_ready; (both use same array/linked list entry?) check if empty Consume() …enqueue Thread 2 Thread 1 return …unlock …dequeue …empty? no …lock Consume() …unlock …signal …lock if so, dequeue Produce() Thread 2 Thread 1 2+ iterations: spurious wakeup or …? 1 iteration: Produce() signalled, probably 0 iterations: Produce() called before Consume() if any are waiting wake one Consume thread other threads can not dequeue here okay because have lock 4
unbounded bufger producer/consumer waiting for Produce() …unlock/start wait …empty? yes …lock Consume() Thread 3 Thread 2 Thread 1 data_ready return Consume() …unlock …dequeue …empty? no lock …unlock stop wait …signal …enqueue …lock Produce() …lock …enqueue …empty? yes data_ready not done by pthreads, Java, … called “Hoare scheduling” signalled thread gets lock next alternate design: gaurenteed to hold lock next in pthreads: signalled thread not lock waiting for lock waiting for waiting for …signal …unlock/start wait …empty? yes return …lock …unlock …dequeue …empty? no lock …unlock stop wait …unlock/start wait …lock pthread_mutex_t lock; pthread_cond_wait(&data_ready, &lock); (both use same array/linked list entry?) simulatenously en/dequeue? otherwise: what if two threads without acquiring lock rule: never touch buffer } return item; pthread_mutex_unlock(&lock); } while (buffer.empty()) { Consume() pthread_mutex_lock(&lock); Consume() { } pthread_mutex_unlock(&lock); pthread_cond_signal(&data_ready); buffer.enqueue(item); pthread_mutex_lock(&lock); Produce(item) { UnboundedQueue buffer; pthread_cond_t data_ready; (both reallocate array?) check if empty if so, dequeue …enqueue Thread 2 Thread 1 return …unlock …dequeue …empty? no …lock Consume() …unlock …signal …lock okay because have lock Produce() Thread 2 Thread 1 2+ iterations: spurious wakeup or …? 1 iteration: Produce() signalled, probably 0 iterations: Produce() called before Consume() if any are waiting wake one Consume thread other threads can not dequeue here 4 item = buffer.dequeue();
unbounded bufger producer/consumer waiting for Produce() …unlock/start wait …empty? yes …lock Consume() Thread 3 Thread 2 Thread 1 data_ready return Consume() …unlock …dequeue …empty? no lock …unlock stop wait …signal …enqueue …lock Produce() …lock …enqueue …empty? yes data_ready not done by pthreads, Java, … called “Hoare scheduling” signalled thread gets lock next alternate design: gaurenteed to hold lock next in pthreads: signalled thread not lock waiting for lock waiting for waiting for …signal …unlock/start wait …empty? yes return …lock …unlock …dequeue …empty? no lock …unlock stop wait …unlock/start wait …lock pthread_mutex_t lock; pthread_cond_wait(&data_ready, &lock); simulatenously en/dequeue? otherwise: what if two threads without acquiring lock rule: never touch buffer } return item; pthread_mutex_unlock(&lock); item = buffer.dequeue(); } while (buffer.empty()) { (both reallocate array?) pthread_mutex_lock(&lock); Consume() { } pthread_mutex_unlock(&lock); pthread_cond_signal(&data_ready); buffer.enqueue(item); pthread_mutex_lock(&lock); Produce(item) { UnboundedQueue buffer; pthread_cond_t data_ready; (both use same array/linked list entry?) check if empty Consume() …enqueue Thread 2 Thread 1 return …unlock …dequeue …empty? no …lock Consume() …unlock …signal …lock if so, dequeue Produce() Thread 2 Thread 1 2+ iterations: spurious wakeup or …? 1 iteration: Produce() signalled, probably 0 iterations: Produce() called before Consume() if any are waiting wake one Consume thread other threads can not dequeue here okay because have lock 4
Recommend
More recommend