2010-05-24 7 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의 목적을 완전히 무효로하는 unlock을 명시 적으로 호출하고 있습니다. scoped_lock은 RAII (Resource Acquisition is Initialization)를 사용하여 잠금을 획득하고 해제합니다. 더 나은 사용법은 블록 내에 임계 영역을 배치하여 잠금 해제 함수에 대한 명시 적 호출이 아닌 범위가 벗어나는 잠금으로 인해 뮤텍스가 해제되도록하는 것입니다. 범위는 덜 취약하기 때문입니다. 예 :

// 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