Condition Vars & Semaphores - Chad Salinas ::: Data Scientist
Life and times of Chad Salinas
Chad Salinas, golf caddy, data scientist, chad rPubs, recovering chess addict, daddy caddy
1115
post-template-default,single,single-post,postid-1115,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

Condition Vars & Semaphores

How to send a signal to another process

Attribution:  I thank Jerry Cain at Stanford for inspiring the following content

 

Rewrite with Condition Vars:

static mutex forks[5]; 
static size_t numAllowed = 5-1;  
static condition_variable_any cv;
static mutex m;
 
static void waitForPermission() { 
    lock.guard<mutex> lg(m);
    cv.wait(  m , [] { numAllowed > 0 } );
    numAllowed–;
}
 
static void grantPermission() { 
    lock.guard<mutex> lg(m);
    numAllowed++;
    if(numAllowed == 1)  cv.notify_one();
}
 
Semaphore represents a generalized counter with atomic ++ and — with an interminable block on a decrement on 0.
 
class Semaphore { 
    public: 
        Semaphore( int count = 0);
            void wait();   // –, block on 0
            void signal(); // ++
 
    private:
        int count; 
        condition_variable_any cv;
        mutex m;
};
 
 
semaphore :: semaphore(int count) : count(count) { } 
 
void semaphore :: wait() {
    lock.guard<mutex> lg(m);
    cv.wait(m, [ this ] { return count > 0; } );
    count–; 
}
 
void semaphore :: signal() {
    lock.guard<mutex> lg(m);
    count++;
    if( count == 1) cv.notify_one(); 
}
 
How is cv.wait(m, pred) implemented in terms of cv.wait(m)?
 
while(!pred) {
    cv.wait(m);  
}
 
 
We can initialize the semaphore’s count to be a negative integer if it suits our use case.
Condition variable is still more powerful than the semaphore because we can implement richer tests. 
Use semaphore unless condition variable buys us something we need.

 

Final solution using semaphores:

 
static mutex forks[5]; 
static semaphore numAllowed(4);  
 
static void eat(size_t id) { 
    size_t right = id;
    size_t left = (id + 1) % 5; 
    
    numAllowed.wait(); 
    forks[right].lock();
    sleep_for(getEatTime()); 
 
     numAllowed.signal(); 
     // release the forks
    forks[right].unlock();
    forks[left].unlock();
}
 

How to schedule a signal using semaphore? 

Why, we might want to limit the number of threads? 

//semaphore class also has a public method:  
void signal(on_thread_exit );  // signal it’s ok to spawn another thread b/c this one finished

 

Troubleshooting Concurrency Issues

p_threads back the C++ thread library.  So, compile with debugging symbols.  Crack open GDB.  Look at the current lwp (aka Light-Weight-Process). 
Use GDB commands: 
  • backtrace
  • thread info
Find out what the threads are hung up on to direct your investigation.  
 

Any programming problem can be solved by adding a level of indirection.

– David J. Wheeler

No Comments

Sorry, the comment form is closed at this time.