2010-04-21 5 views
0

제한된 리소스 세트가 포함 된 "Manager"클래스를 만들었습니다. 자원은 "Manager"에 대기열로 저장됩니다. 큐와 세마포어를 동일한 크기로 초기화하고, 사용 가능한 리소스가없는 경우 세마포어를 사용하여 스레드를 차단합니다. 리소스를 요청하기 위해이 클래스를 호출하는 여러 스레드가 있습니다. 다음은 가짜 코드입니다.세마포어 경쟁 조건?

public IResource RequestResource() 
{ 
    IResource resource = null; 
    _semaphore.WaitOne(); 

    lock (_syncLock) 
    { 
     resource = _resources.Dequeue(); 
    } 
    return resource; 
} 
public void ReleaseResource(IResource resource) 
{ 
    lock (_syncLock) 
    { 
     _resources.Enqueue(resource); 
    } 
    _semaphore.Release(); 
} 

이 응용 프로그램을 실행하는 동안 잠시 동안 제대로 실행되는 것 같습니다. 그런 다음, 내 큐가 같은 대상을 내고있는 것 같습니다. 이것이 가능한 것처럼 보입니까? 나는 내 머리카락을 끌어 당기고 있으며 어떤 도움도 크게 감사 할 것입니다. 필요할 경우 언제든지 자세한 정보를 요청하십시오. 감사!

+1

pls를 다시 포맷하고 이것을 호출하는 코드를 제공 할 수 있습니까? –

+0

예, 죄송합니다. 탭에 붙여 넣은 다음 원래 미리보기에서 제대로 보였다고 생각했습니다. – poindexter12

+0

대기열 크기가 변경되면 변경됩니까? 객체가 다른 스레드에서도 동일합니까? 전화 패턴은 무엇입니까? Enqueue와 Dequeue가 예외를 throw 했습니까 (버그가 있습니다.) 디버깅을 시도 했습니까? –

답변

2

세마포어는 실제로 부수적입니다. 동시에 자원을 확보 할 수있는 소비자의 수를 제한합니다. 동기화는 실제로 lock 문 (중요 섹션)에서 이루어집니다.

내가 알 수있는 한,이 코드는 스레드로부터 안전합니다. "같은 객체를 내고있다"고 말할 때, 아마도 질문을 오해하고있는 것 같지만, 이 같은 객체를 제공해야합니다. 호출자가 Release 메소드를 호출 할 때, 동일한 객체가 실행 중 여러 지점에서 대기열에있게됩니다.

  1. 큐에서 중복 된 자원이 포함 : 당신이 의미하는 것은 RequestResource 방법은 이미 획득하지만 발표되지 않은 반환 자원이다 경우

    , 내가 생각할 수있는 유일한 세 가지 이유가있다 처음;

  2. 소비자가 Release 메서드를 두 번 호출했습니다. Release 방법에서는 자원이 이미 대기열에 있는지 여부를 실제로 확인하지 않습니다. 이 코드를 변경하고 예외를 던지려면이 코드를 변경하여 Release 호출이 복제되는 위치를 파악하는 데 도움이 될 수 있습니다 (사실 경우).

  3. 일부 다른 코드는 lock없이 _resources 큐에 액세스하고 있습니다.

복제본이 실제로 의미하는 것이면 의심 될 것입니다. Aaronaught의 대답에 추가

+0

지금 2 번 시도, 결과를 알려주십시오. 번호 하나는 일어나지 않습니다. _resources는 private이며 두 메서드 호출 외부에서 액세스 할 수 없으므로 문제가 아닌 것으로 생각됩니다. – poindexter12

+0

이것은 문제를 해결하는 것으로 보이지 않습니다. 처리량을 좀 더 원자 적으로 만들려고 노력 중이므로이 오류를 줄이려고 노력할 수 있습니다. 이게 내 문제를 해결하면 여전히 투표를합니다 :) – poindexter12

0

는 두 개의 스레드가 세마포어를 획득 한 후 하나 RequestResource()에서 중요한 부분을 입력하고, 첫 번째 스레드가 모두 완료 한 다음에 다른 블록에 대한

또한 전적으로 가능 보인다 그 작업과 ReleaseResource()와 함께 대기열에 개체를 반환 두 번째 스레드가 깨어나고 dequeue 기회가 전에. 그러면 동일한 객체를 얻는 두 개의 스레드에 대한 인상을 줄 수 있습니다.

+0

, 당신이 옳습니다. IResource는 작업을하기 위해 약 10 초가 걸리기 때문에 실제로 문제가되지 않습니다. "자원"은 작업이 다른 스레드에 의해 완료되면 다시 사용됩니다. 나는 "자원"이 다른 스레드에 의해 동시에 사용되고 있다는 것을 알 수 있습니다. 프로세스가 매우 동기적이고 처리의 중간에 시작되어서 내 응용 프로그램을 파괴하기 때문입니다. – poindexter12

관련 문제