100 likes | 207 Vues
This document outlines the implementation of the Producer-Consumer problem in C using locks and condition variables. It describes the usage of a character buffer, ensuring safe access for multiple threads through proper locking mechanisms. The examples illustrate how to add and remove items from the buffer while handling edge cases such as buffer overflow and underflow. The notes cover the initialization of locks, buffer operations, and the implementation of waiting conditions to manage producer-consumer synchronization in a concurrent environment.
E N D
Both threads: struct lock l; ... lock_acquire(&l); if (milk == 0) { buyMilk(); } lock_release(&l); Too Much Milk With Locks CS 140 Lecture Notes: Concurrency
char buffer[SIZE]; int count = 0; int head = 0, tail = 0; struct lock l; lock_init(&l); void put(char c) { lock_acquire(&l); count++; buffer[head] = c; head++; if (head == SIZE) { head = 0; } lock_release(&l); } char get() { char c; lock_acquire(&l); count--; c = buffer[tail]; tail++; if (tail == SIZE) { tail = 0; } lock_release(&l); return c; } Producer/Consumer v1 CS 140 Lecture Notes: Locks
char buffer[SIZE]; int count = 0; int head = 0, tail = 0; struct lock l; lock_init(&l); void put(char c) { lock_acquire(&l); count++; buffer[head] = c; head++; if (head == SIZE) { head = 0; } lock_release(&l); } char get() { char c; lock_acquire(&l); count--; c = buffer[tail]; tail++; if (tail == SIZE) { tail = 0; } lock_release(&l); return c; } Producer/Consumer v1 put('a'); a count: 0 head: 0 tail: 0 SIZE: 8 count: 1 head: 1 tail: 0 SIZE: 8 CS 140 Lecture Notes: Locks
char buffer[SIZE]; int count = 0; int head = 0, tail = 0; struct lock l; lock_init(&l); void put(char c) { lock_acquire(&l); count++; buffer[head] = c; head++; if (head == SIZE) { head = 0; } lock_release(&l); } char get() { char c; lock_acquire(&l); count--; c = buffer[tail]; tail++; if (tail == SIZE) { tail = 0; } lock_release(&l); return c; } Producer/Consumer v1 put('b'); put('c'); a a b c count: 0 head: 0 tail: 0 SIZE: 8 count: 3 head: 3 tail: 0 SIZE: 8 CS 140 Lecture Notes: Locks
char buffer[SIZE]; int count = 0; int head = 0, tail = 0; struct lock l; lock_init(&l); void put(char c) { lock_acquire(&l); count++; buffer[head] = c; head++; if (head == SIZE) { head = 0; } lock_release(&l); } char get() { char c; lock_acquire(&l); count--; c = buffer[tail]; tail++; if (tail == SIZE) { tail = 0; } lock_release(&l); return c; } Producer/Consumer v1 get() => 'a' a b c a b c count: 3 head: 3 tail: 0 SIZE: 8 count: 2 head: 3 tail: 1 SIZE: 8 CS 140 Lecture Notes: Locks
char buffer[SIZE]; int count = 0; int head = 0, tail = 0; struct lock l; lock_init(&l); void put(char c) { lock_acquire(&l); count++; buffer[head] = c; head++; if (head == SIZE) { head = 0; } lock_release(&l); } char get() { char c; lock_acquire(&l); count--; c = buffer[tail]; tail++; if (tail == SIZE) { tail = 0; } lock_release(&l); return c; } Producer/Consumer v1 get() => 'b' a b c a b c count: 2 head: 3 tail: 1 SIZE: 8 count: 1 head: 3 tail: 2 SIZE: 8 CS 140 Lecture Notes: Locks
char buffer[SIZE]; int count = 0; int head = 0, tail = 0; struct lock l; lock_init(&l); void put(char c) { lock_acquire(&l); count++; buffer[head] = c; head++; if (head == SIZE) { head = 0; } lock_release(&l); } char get() { char c; lock_acquire(&l); count--; c = buffer[tail]; tail++; if (tail == SIZE) { tail = 0; } lock_release(&l); return c; } Producer/Consumer v1 put('h'); put('i'); a b c d e f g i b c d e f g h count: 5 head: 7 tail: 2 SIZE: 8 count: 7 head: 1 tail: 2 SIZE: 8 CS 140 Lecture Notes: Locks
char buffer[SIZE]; int count = 0; int head = 0, tail = 0; struct lock l; lock_init(&l); void put(char c) { lock_acquire(&l); while (count == SIZE) { lock_release(&l); lock_acquire(&l); } count++; buffer[head] = c; head++; if (head == SIZE) { head = 0; } lock_release(&l); } char get() { char c; lock_acquire(&l); while (count == 0) { lock_release(&l); lock_acquire(&l); } count--; c = buffer[tail]; tail++; if (tail == SIZE) { tail = 0; } lock_release(&l); return c; } Producer/Consumer v2 CS 140 Lecture Notes: Locks
char buffer[SIZE]; int count = 0; int head = 0, tail = 0; struct lock l; struct condition dataAvailable; struct condition spaceAvailable; lock_init(&l); cond_init(&dataAvailable); cond_init(&spaceAvailable); void put(char c) { lock_acquire(&l); while (count == SIZE) { cond_wait(&spaceAvailable, &l); } count++; buffer[head] = c; head++; if (head == SIZE) { head = 0; } cond_signal(&dataAvailable, &l); lock_release(&l); } char get() { char c; lock_acquire(&l); while (count == 0) { cond_wait(&dataAvailable, &l); } count--; c = buffer[tail]; tail++; if (tail == SIZE) { tail = 0; } cond_signal(&spaceAvailable, &l); lock_release(&l); return c; } Producer/Consumer v3 T1 T2 T3 CS 140 Lecture Notes: Locks