2013-10-09 2 views
2

wikipedia에 언급 된 생산자 소비자 문제의 '부적절한 구현'에 대한 의사 코드는 다음과 같습니다. 이 솔루션은 교착 상태를 일으킬 수있는 경쟁 조건이 있다고합니다.멀티 스레드 프로그래밍 - 생산자 소비자

내 질문은 : 가능한 한 교착 상태 문제를 해결하기 위해 다른 스레드를 깨우는 조건을 수정하지 않았습니까? 그런 식으로 잃어 버릴 수있는 하나의 깨우기가 아니라 다음에 여러 깨우기가 있습니다. 아니면 뭔가 빠져 있습니다. 여기에서 이해하려고 노력합니다.

int itemCount = 0; 

procedure producer() { 
    while (true) { 
     item = produceItem(); 

     if (itemCount == BUFFER_SIZE) { 
      sleep(); 
     } 

     putItemIntoBuffer(item); 
     itemCount = itemCount + 1; 

     //if (itemCount == 1) <<<<<<<< change this to below condition 
     if(itemCount > 0) 
     { 
      wakeup(consumer); 
     } 
    } 
} 

procedure consumer() { 
    while (true) { 

     if (itemCount == 0) { 
      sleep(); 
     } 

     item = removeItemFromBuffer(); 
     itemCount = itemCount - 1; 

     //if (itemCount == BUFFER_SIZE - 1) <<<<<<< Change this to below 
     if(itermCount < BUFFER_SIZE) 
     { 
      wakeup(producer); 
     } 

     consumeItem(item); 
    } 
} 

답변

1

는 다른 아래 스레드 가능한 교착 상태 문제를 해결을 wakeing의 조건을 수정하지 않을 것입니다.

아니요, 경쟁 조건이 여전히 존재합니다. 문제는 소비 및/또는 생산을하는 여러 스레드가 있다는 것입니다. 소비자 (예 :)가 깨어나서 처리 할 항목이 있다고 말하면 항목을 제거하지만 일부 다른 스레드 (또는 스레드)가 그 항목 앞에 놓이게됩니다.

이 솔루션은 다음을 수행하는 것입니다

lock() { 
    while (itemCount == 0) { 
     sleep(); 
    } 

    item = removeItemFromBuffer(); 
    itemCount = itemCount - 1; 
} 

그래서 소비자가 각성 경우에도 즉시 다시 itemCountwhile 루프 0이 아닌을 을 확인합니다. itemCount이 증가했지만 다른 스레드가 해당 요소를 제거하고 itemCount을 감소한 후 신호를받은 스레드가 작동 할 수있는 기회가있었습니다. 그것은 경주입니다.

생산자가 버퍼를 과도하게 채우지 못하도록하는 경쟁이긴하지만 제작자 측에서도 동일합니다. 프로듀서는 사용 가능한 공간이 있기 때문에 깨우쳐 질 수 있습니다.하지만 버퍼에 항목을 넣을 때까지 다른 스레드가 버퍼를 채우고 버퍼를 다시 채 웁니다. 그것이 깨어 난 후에 공간이 있는지 확인하기 위해 다시 테스트해야합니다.

본 웹 사이트의이 페이지에 대한 자세한 내용은 Producer Consumer Thread Race Conditions입니다. 거기에 문제를 보여주는 작은 테스트 프로그램도 있습니다.

실현해야 할 중요한 점은 대부분의 잠금 구현에는 잠금에 대한 액세스를 기다리는 대기열이 있다는 것입니다. 신호가 쓰레드로 보내지면, 먼저 을 되찾아서 자물쇠, 전에 전에 계속할 수 있습니다. 스레드가 신호를 받으면 블록 대기열의 으로갑니다. 잠금을 기다리는 추가 스레드가 있지만 이 아닌 경우이 대기 스레드보다 먼저 실행되어 항목을 도용합니다.

이것은 비슷한 코드의 while 루프에 관한이 질문과 매우 유사합니다. 불행하게도이 대답은이 경쟁 조건을 해결하지 못합니다. upvoting my answer to a similar question here을 고려하십시오. 가짜 웨이크 업 이지만 실제 문제는 위키피디아가 말하는 경쟁 조건입니다.

+1

또한 'itemCount'를 수정하는 모든 줄은 원 자성이거나 잠겨 있어야합니다. – Adam

+0

그냥 @Adam을 고쳤습니다. 감사. – Gray

+0

여러 소비자 생산자 경우에 웨이크 업을 모든 스레드로 보내지 않아야합니까? 그런 식으로 경기를 피할 수 있을까요? – goldenmean