Computer Science
Concurrency :::: Ice Cream Parlor example
Ice Cream Parlor Example
Manager
1 Manager
Only interfaces with one clerk at a time
Clerk presents one cone to manager at a time
Manager approves/rejects cones
Clerks
Prepare one cone at a time
Present to manager for approval
On approval clerk hands customer a cone
10-40 clerk threads through the life of the program
Live only as long as it takes to make a cone that gets approved
Customers
3rd thread category
10 customer threads
each customer requests between 1-4 cones
spawn 1-4 clerk threads (grandchild threads)
Cashier
rings up each of the 10 customer threads
then dies
// globals
struct {
bool passed; // initially false
mutex available; // initially unlocked
semaphore requested; // initially 0
semaphore finished; // initially 0
} inspection;
struct {
atomic<int> placeInLine; // init to 0; guarantee ++ is atomic
semaphore numWaiting;
semaphore rungUp[10];
} line; // a queue of customers
Main()…
int main() {
int totalCones = 0;
thread customers[10];
for(size_t i = 0; i < 10; i++) {
int numCones = randInt(1,4);
totalCones += numCones;
customers[i] = thread(customer, i+1, numCones);
}
thread m(manager, totalCones);
thread c(cashier);
// thread joins go here
}
static void customer(int id, int numCones) {
vector<thread> clerks; // thread clerks[numCones];
for(size_t i = 0; i < numCones; i++) {
clerks.push_back(thread(clerk, i+1, id));
}
browse(); // give time for clerk/manager creation/approval
for(thread& t:clerks) t.join();
int place = line.placeInLine++;
line.numWaiting.signal();
line.rungUp[place].wait();
}
static void clerk(int id, int custId) {
bool passed = false; // clerk has not produced an approved cone
while(!passed) {
makeCone(id, custId); // some thread-safe routine to keep making cones
inspection.available.lock();
inspection.requested.signal();
inspection.finished.wait();
passed = inspection.passed; // update local var for this ice cream cone
inspection.available.unlock();
}
// 2 types of thread coordination:
// 1. race condition for manager’s attention – guard with a mutex
// 2. bi-directional rendezvous implanted into thread manager interaction
// to let manager know 1+ clerks are waiting; to let clerk know if cone approved
}
static void manager(int numNeeded) {
int numApproved = 0;
int numAttempted = 0;
while(numApproved < numNeeded) {
inspection.requested.wait();
inspection.passed = randomChance(0.3); // inspect cone
inspection.finished.signal();
numAttempted++;
if(inspection.passed) numApproved++;
count << oslock << “… ” << osunlock ;
}
}
static void cashier() {
for(size_t i = 0; i < 10; i++) {
line.numWaiting.wait();
ringUpCustomer();
line.rungUp[i].signal();
}
}
Sorry, the comment form is closed at this time.