2013-06-06 2 views
1

모니터를 사용할 때 모든 객체에 대기열 및 준비 대기열이있는 이유는 무엇입니까? 객체로 스레드가 완료되면 대기 대기열의 다음 항목을 팝합니다. 준비 대기열이 중복 된 것처럼 보입니다.대기열 대 준비 대기열

컨텍스트는 .NET, 특히 모니터 클래스입니다.

+0

상황을 설명해야합니다. 이 질문에 당신이 도착했을 때 뭔가를 읽고 있었습니까? 그렇다면 여기에 링크하거나 문맥을 반복하십시오. –

+0

".NET에서"- 어떤 클래스입니까? 감시 장치? 다른 것? – mbeckish

+0

.NET과 달리 Windows 스레딩에 대해 말하는 것처럼 들립니다. 명확히하십시오. –

답변

2

귀하의 질문을 올바르게 이해했다고 가정하면 두 가지 목적이 다릅니다.

대기열은 잠금을 얻을 수있는 즉시 실행할 준비가 된 스레드를위한 것입니다. 그들은 단지 자물쇠를 얻기 위해 기다리고 있습니다. 이것은 주로 상호 배제에 사용되어 두 스레드가 동시에 같은 자원을 사용하지 못하도록합니다.

"대기 중"대기열은 특정 신호을 기다리고있는 스레드, 즉 모니터가 펄스되는 대기열입니다. 이것은 종종 생산자/소비자 대기열에서 조정을 위해 사용됩니다. 예를 들어 생산자/소비자 대기열에서 대기열이 비어있는 경우 소비자는 대기열을 다시 확인하기 전에 모니터에 펄스가 발생할 때까지 대기합니다. 아무도 생산하지 않고 아무도 소비하지 않는 동안 아무 스레드도 모니터를 소유하지 않습니다. 사용중인 리소스가 없습니다. 그러나 모니터는 생산자와 소비자를 조정하는 데 사용됩니다.

+1

... 질문을 묻는 질문을 이해하기 위해 부두 마음 읽기를 사용하십시오. –

+0

@TimothyShields : 글쎄, 나는 "ready queue"와 "waiting queue"를 찾고이 질문을 찾았습니다 : http://stackoverflow.com/questions/12121151/monitor-pulse-wait-unexpected-behaviour -이게 의심 스럽네요. 동일한 용어를 사용합니다. –

+0

그래서 맥박은 무언가가 준비 될 때마다 소비자에게 알릴 것이고, 그 동안 소비자 스레드는 다른 것들을 할 수 있습니다. 펄스는 대기열에있는 스레드에만 알리고 이러한 스레드는 이미 차단되어있어 아무 것도 할 수 없기 때문에 가능하지 않다고 생각합니다. – Yamcha

2

생산자/소비자 대기열은 Monitor 클래스에 대해 학습 할 때 매우 유용합니다.

작업이 간헐적으로 대기열에 추가된다고 가정하십시오. 때로는 처리해야 할 항목이 많으며 대기열에 항목이 없으면 오랜 시간이 경과하는 경우가 있습니다.

그래서 대기열의 항목을 처리하기 위해 대기중인 k 개의 소비자 스레드가 있다고 가정 해 보겠습니다. 즉, 각 스레드는 지속적으로 (이 모니터의 "준비"큐에 넣) 큐에 lock를 얻을 수

  1. 요청에 노력하고, 꽉 루프를 구현합니다.
  2. 잠금이 해제되면 대기열에 항목이 있는지 확인하십시오. 그렇지 않으면 자물쇠를 해제하는 두 가지 선택 사항이 있습니다. a) Monitor.Exit을 호출 한 다음 Monitor.Enter를 호출하여 "대기"대기열의 뒷면에 놓습니다. b) 또는 Monitor.Wait를 호출하고 모니터의 "대기중인"대기열에 자신을 넣습니다.

"a"옵션을 선택하면 k 스레드가 준비 대기열을 계속 이동하면서 반복적으로 작업을 수행하지 않고 대기열 뒤쪽에서 다시 시작하는 CPU 사이클을 낭비하게됩니다.

"b"옵션을 선택하면 "지금 당장 할 일이 없으며 잠자기 상태로 만들거나 할 일이있을 때 나를 깨울 수 있습니다."라고 말하는 것입니다.

"b"옵션을 사용하면 대기열이 비어있는 경우 대기중인 대기열에서 잠자고있는 모든 소비자를 곧 찾을 수 있으며 낭비되는 CPU 시간도 없습니다.

그런 다음 제작자가 항목을 대기열에 추가하면 Monitor.Pulse가 호출됩니다. 이것은 "대기 중"대기열의 첫 번째 스레드를 깨우고 "대기"대기열의 뒤쪽으로 이동합니다. 대기열은 준비 대기열이 비어있는 경우 대기열의 맨 앞에 있습니다.

스레드가 잠금을 가져 와서이 항목을 대기열에서 소비하면 Monitor.Enter를 다시 호출하고 "대기"대기열의 뒤로갑니다.

.NET에서 생성자/소비자 대기열의 기본 구현을 보려면 this article을 참조하십시오.

+0

상세한 답변을 보내 주셔서 감사합니다.하지만 대기중인 대기열 (대기중인 대기열의 대기열)만으로 쉽게 아이디어를 구현할 수 있습니다. Monitor.Pulse를 호출하여 대기열의 첫 번째 요소를 대기열에서 제외 할 수없는 이유는 무엇입니까? 즉, 대기열에 들어가야하는 이유는 무엇입니까? – Yamcha

+0

@ user1316459 - 소비자가 이미 깨어 있고 통화 중이기 때문에 Task Queue에 더 많은 항목이 추가되면서 모든 소비자가 사용 중이라고 가정 해 봅시다 (모든 Monitor.Pulse 호출은 사용되지 않습니다). 대기열 만 있으면 각 소비자가 현재 작업을 마칠 때 대기 대기열에서 잠자기 상태로 돌아가고 들어오는 새로운 작업을 처리 할 소비자가 없습니다. – mbeckish

+0

@ user1316459 - "그러나 당신의 아이디어는 단지 대기열로 구현 될 수 있습니다". 나는 그것을 당신이 블로그에 공개 할 수 있도록 초대합니다. 어쩌면 당신은 새로운 것을 만들어 낼 것입니다. 아니면 그렇지 않겠지 만 그 길을 따라 모든 문제를 깊이있게 이해하게 될 것입니다. – mbeckish

관련 문제