2010-05-24 55 views
1

我正準備在幾周內接受採訪,我想提出一些建議,以及我在學校學到的簡單生產者/消費者問題。生產者/消費者實施 - 反饋通緝

還沒有完成它,所以我很好奇你們對此有何看法?我應該添加什麼來使其成爲更好的示例等。感謝您的反饋! :)

////////////////////////////////////////////////////////////////////////// 
boost::mutex bufferMutex; 
deque<int> buffer; 
const int maxBufferSize = 5; 
////////////////////////////////////////////////////////////////////////// 

bool AddToBuffer(int i) 
{ 
    if (buffer.size() < maxBufferSize) 
    { 
     buffer.push_back(i); 
     return true; 
    } 
    else 
    {  
     return false; 
    } 
} 

bool GetFromBuffer(int& toReturn) 
{ 
    if (buffer.size() == 0) 
    { 
     return false; 
    } 
    else 
    { 
     toReturn = buffer[buffer.size()-1]; 
     buffer.pop_back(); 
     return true; 
    } 
} 

struct Producer 
{ 
    int ID; 
    void operator()() 
    { 
     while (true) 
     { 
      boost::mutex::scoped_lock lock(bufferMutex); 
      int num = dice(); 
      bool result = AddToBuffer(num); 
      lock.unlock(); 
      //safe area done 
      if (result) 
      { 
       cout << "Producer " << this->ID << " Added " << num << endl; 
      } 
      else 
      { 
       cout << "!!Buffer was Full!!" << endl; 
      } 
      //Added 
      //Now wait 
      boost::xtime xt; 
      xtime_get(&xt, boost::TIME_UTC); 
      xt.nsec += 1000000 + 100000 * (rand() % 1000); 
      boost::thread::sleep(xt); 
     } 
    } 
}; 

struct Consumer 
{ 
    int ID; 
    void operator()() 
    { 
     while (true) 
     { 
      int returnedInt = 0; 
      boost::mutex::scoped_lock lock(bufferMutex); 
      bool result = GetFromBuffer(returnedInt); 
      lock.unlock(); 
      //safe area done 
      if (result) 
      { 
       cout << "\tConsumer " << this->ID << " Took Out " << returnedInt << endl; 
      } 
      else 
      { 
       cout << "!!Buffer was Empty!!" << endl; 
      } 
      //Added 
      //Now wait 
      boost::xtime xt; 
      xtime_get(&xt, boost::TIME_UTC); 
      xt.nsec += 1000000 + 100000 * (rand() % 1000); 
      boost::thread::sleep(xt); 
     } 
    } 
}; 



void main() 
{ 
    Producer p, p2; 
    Consumer c, c2; 

    p.ID = 1; 
    p2.ID = 2; 

    c.ID = 1; 
    c2.ID = 2; 

    boost::thread thread1(boost::ref(p)); 
    boost::thread thread2(boost::ref(c)); 
    boost::thread thread3(boost::ref(p2)); 
    boost::thread thread4(boost::ref(c2)); 

    int x; 
    cin >> x; 
} 

回答

3

如果你已經包裹在像AddToBuffer和GetFromBuffer呼叫您的緩衝區對象,那就更有意義了,你把你的包裝函數內的鎖定。另外,你正在做一個明確的解鎖調用,這完全違背了scoped_lock的目的; scoped_lock使用資源獲取初始化(RAII)來獲取和釋放鎖。一個更好的用法是將關鍵部分放在一個塊中,以便由於鎖定超出範圍而不是由於顯式調用解鎖函數而釋放互斥鎖,因爲範圍不那麼脆弱。例如:

// Code that doesn't need locking 
{ 
    boost::mutex::scoped_lock lck(bufferMutex); // Lock is acquired here 
    // Code that needs to be synchronized 
} // Lock is automatically released here without explicit call to unlock() 
// More code that doesn't need locking 
+1

感謝您的評論! :) – bobber205 2010-05-24 21:46:00