C++ Thread Library - Chad Salinas ::: Data Scientist
Life and times of Chad Salinas
Chad Salinas, golf caddy, data scientist, chad rPubs, recovering chess addict, daddy caddy
1066
post-template-default,single,single-post,postid-1066,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

C++ Thread Library

C++ Thread Library

Attribution:  I thank Jerry Cain at Stanford for inspiring the following content
 
C++ Thread package

 
introverts example in C++
 
static void recharge() {
   //  cout << is not MT Safe, so we need to use locks
    cout << oslock <<  “I recharge by spending time alone.”  << endl << osunlock;
 
}
 
int main(int argc, char *argv[]) {
    cout << “Let’s hear from 6 introverts. ” << endl;
    thread introverts[6];  // objects with a thread routine defaultly constructed into them
    for (thread &t : introverts) {
        t = thread(recharge);     // construct the thread around the recharge function
    }
 
    for (thread &t : introverts) {
        t.join();
    }
    cout << “Everyone is recharged. ” << endl;
    return 0 ;
}
 
Now, we progress from no argument thread routine to one that takes an argument
Greeters example
 
Each greeter has a given id and says hello, id number of times before ending as a thread.
 
static void greet(size_t id) {
    for( size_t count = 0; count < id; count++) {
        cout << oslock << “Greeter # ” << id << ” says \”hello\”” << endl << osunlock;
        sleep_for(random() % 1000000);  // introduce some variation into wait time
    }
 
    cout << oslock << “Greeter # ” << id << ” all done” << endl << osunlock;
}
 
int main() {
    cout << “Welcome to Greetland!” << endl;
    thread greeters[6];
    for(size_t i = 0; i < 6; i++) {
        greeters[i] = thread(greet, i+1);
    }
    for( thread &t : greeters) {
        t.join();
    }
    cout << “All done! ” << endl;
    return 0;
}
 
 

Airline Ticket Agent example to illustrate the need for a mutex

Each of 10 ticket agents tries to sell airline tickets until 100 total tickets are sold.

 
static int numTickets = 100;
 
static void agent(size_t id) {
 
    while(numTickets > 0) {
        numTickets–;   // sell a ticket
        cout << oslock << “Sold a ticket…” , id, numTickets << endl << osunlock;
        if (shouldTakeBreak()) {   // introduce randomness to influence thread scheduler
            takeBreak();
        }
    }
}
 
Problem:  numTickets– is not atomic.  What if a thread commits to sell a ticket by going into the while loop and gets swapped off the processor before completely executing numTickets–;  Thread has not flushed out the new value to the global variable: numTickets;
 
While loop test is separated from the decrement.
 
// boilerplate correct main()
int main() {
    thread agents[10];
    for ( size_t i = 0; i < 10; i++) {
        agents[i] = thread(agent, 101+i);
    }
    for (thread &t : agents) {
        t.join();
    }
   return 0;
}
 

No Comments

Sorry, the comment form is closed at this time.