0 Replies - 3057 Views - Last Post: 18 October 2012 - 11:46 AM Rate Topic: -----

#1 Rumsy   User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 26
  • Joined: 30-January 11

Problems With Semaphores

Posted 18 October 2012 - 11:46 AM

Hello Dream,

I'm posting because I have been running into issues using semaphores to implement a "one-lane construction zone" with the following rules:

1. Neither a car nor a pedestrian wait if the zone is empty
2. Cars can not go in separate directions at the same time
3. A car may enter the intersection if there is another car going the same direction but cars cannot pass eachother
4. A car does not wait for more than two cars going the opposite direction before it goes
5. A pedestrian has to yield to cars but should not wait for more than two cars in any direction

Here are the global declarations ( :sweatdrop: ):
semaphore ent(1), ext(1), car_east(1), car_west(1);
int ecount=0, wcount=0, totalcars=0;



Here are my functions for each:
  
void carEast()
{                
  car_east.wait();   
    ent.wait();                                               
        //next east sleeps if 2 consecutive east cars have crossed
        if(ecount<2){car_east.signal();}

        //cmd_list[tmp] is id of thread              
        cout << cmd_list[tmp] << " entering construction\n";
        ++ecount;                                             
        wcount=0;                                             
    ent.signal();                                             
                                                              
    ext.wait();                                               
        //sleep for time to travel through crossing
        //1ms to make testing quicker           
        std::this_thread::sleep_for(chrono::milliseconds(1)); 
        cout << cmd_list[tmp] << " exiting construction\n";
        ++totalcars;                                          
    ext.signal();                                             
}


  
void carWest()
{                
  car_west.wait();   
    ent.wait();                                               
        if(wcount<2){car_west.signal();}              
        cout << cmd_list[tmp] << " entering construction\n";
        ++wcount;                                             
        ecount=0;                                             
    ent.signal();                                             
                                                              
    ext.wait();                                                         
        std::this_thread::sleep_for(chrono::milliseconds(1)); 
        cout << cmd_list[tmp] << " exiting construction\n";
        ++totalcars;                                          
    ext.signal();                                             
}


 
void Pedestrian()
{
while(totalcars<2)                                            
{                                                             
    //When total of 2 cars have crossed consecutively, ped is ready to cross
}                                                             
                                                              
    car_east.wait(); //put future cars to sleep                  
    car_west.wait();                                          
    ent.wait();                                               
        cout << cmd_list[tmp] << " entering construction\n";
    ent.signal();                                             
                                                              
    ext.wait();                                                         
        std::this_thread::sleep_for(chrono::milliseconds(1)); 
        totalcars=0; //reset consecutive counters for cars    
        ecount=0;                                             
        wcount=0;                                             
        cout << cmd_list[tmp] << " exiting construction\n";
    ext.signal();                                             
    
    //Signals cars but does not allow multiple pedestrians to cross at
    //once?                                                          
    car_east.signal();
    car_west.signal();
}



And here is the semaphore implementation:
class semaphore{
 private:
  mutex m;
  condition_variable_any cv;
  int count;
 public:
  semaphore(int c){
    count=c;
  }

 void wait(void){
    m.lock();
    while (count <= 0)
      cv.wait(m);
    count--;
    m.unlock();
  }

  void signal(void){
    m.lock();
    count++;                                                  
    cv.notify_one();                                          
    m.unlock();    
  }
}



There are only 4 threads in my test that are created in the following order: E1, P1, E2, W1
Example output should read as follows:
E1 entering construction
E2 entering construction
E1 exiting construction
E2 exiting construction
P1 entering construction
P2 exiting construction
W1 entering construction
W1 exiting construction


Some previous variations of my code produced almost the correct answer but as well as being off proved to be less predictable. So I guess I'm asking for a hint solving the problem, if I'm implementing semaphores correctly and what I'm missing here.

Thanks,
Rumsy

Is This A Good Question/Topic? 0
  • +

Page 1 of 1