Concurrency :::: Ice Cream Parlor example - Chad Salinas ::: Data Scientist
Use Slidify to create motion charts to share with the world on rPubs Chad Salinas or GitHub.
Slidify, rPubs Chad Salinas, Motion Charts, Hans Rosling
1188
post-template-default,single,single-post,postid-1188,single-format-standard,qode-listing-1.0.1,qode-social-login-1.0,qode-news-1.0,qode-quick-links-1.0,qode-restaurant-1.0,ajax_fade,page_not_loaded,,qode-title-hidden,qode_grid_1300,qode-theme-ver-12.0.1,qode-theme-bridge,bridge,wpb-js-composer js-comp-ver-5.4.2,vc_responsive
a

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

Chad Salinas working on Plotly

Chad Salinas working on analytics project.

Chad Salinas late nighter
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();
    }
}

Let the dataset change your mindset

– Hans Rosling
No Comments

Sorry, the comment form is closed at this time.