C# 모니터 클래스의 멀티 스레딩 문제 - 가능한 생명락?
-
22-07-2019 - |
문제
약간의 코드가있어 제대로 알아낼 수 없습니다. 문제는 프로그램이 멀티 스레드가 있고 거기 내에 동기화되어야하는 약간의 코드가 있으므로 다음을 작성한다는 것입니다.
lock (lockObject)
{
if (!Monitor.TryEnter(lockObject))
Monitor.Wait(lockObject);
//do stuff...
Monitor.PulseAll(lockObject);
}
Monitor.Exit(lockObject);
내가 가진 문제는 어느 시점에서 모든 실이 자고있는 것처럼 보인다는 것입니다. 누군가가 이유를 말할 수 있습니까? 이 프로그램은 거의 CPU가 거의 없지만 계속해서 작업하지는 않지만 작업이 수행되지 않습니다. 프로그램을 추적 할 때 어느 시점에서 실이 활성화되지 않지만 많은 사람들이 자고 있음을 알았습니다. 나는 주로 오류를 알고 있습니다 (개발자의 경우 - 항상 - 항상) 모니터 앞에 0.5m가 있습니다. 그러나 몇 분 안에 스스로 알아낼 수는 없습니다.)
누군가 나에게 설명해 주시겠습니까? 미리 감사드립니다.
해결책
차이가 있습니까? LockObject
그리고 lockObject
? 분명하지 않습니다 ...
하지만! 그들이 다른 물건이라면 먼저 : 당신은 Wait
당신이 가지고 있지 않은 자물쇠에 ... 그리고 TryEnter
시간 초과를 지정하는 경우에만 False를 반환합니다. 그 코드는 정확히 무엇을하려고합니까?
더 많은 맥락이 없다면 PulseAll
그리고 Wait
할 수 있도록 설계되었습니다. 예를 들어, 여기 대기열이 너무 가득 차있을 때 큐를 차단하는 데 사용됩니다 (Wait
) 또는 공간을 사용할 수있게되면 해제하십시오 (PulseAll
), 등. 스레드 간의 전체 상호 작용없이 스레딩 코드를 디버깅하기가 어렵습니다.
필요한 것 같습니다.
lock (lockObject)
{
// do stuff
}
내가 볼 수있는 두 가지 즉각적인 문제가 있습니다. 첫째, 항상 당신이 취하는 자물쇠를 릴리스하는 것은 분명하지 않습니다 (예 : 예외). 그냥 사용하십시오 lock
용 Enter/Exit
- 제대로 될 것입니다.
초; 모든 스레드가 호출되는 경우 Wait
... 누가 그들을 깨울까요? 그들은 무엇을 기다리고 있습니까? ~을 위한? 제시된 바와 같이 : 그렇습니다. 그들은 모두 무기한으로 잠을 잘 것입니다.
다른 팁
첫 번째 잠금 문은 오타이고 잠금 (Lockobject) (소문자)을 의미합니다.
나는 당신이 여기서 잠금을 약간 오해하고 있다고 생각합니다. 코드의 IF 블록은 사실이 아닙니다. 그 이유는 그 자물쇠 (lockobject)가 실제로 다음을 추방합니다.
Monitor.Enter(lockObject);
try {
...
} finally{
Monitor.Exit(lockObject);
따라서 IF 블록을 때릴 때 이미 잠금 장치를 소유하고 있으며 Tryenter는 항상 성공해야합니다.
그것은 이상한 설정입니다. 'lockobject'는 'lockobject'와 동일합니까? 아니면 오타입니까? 동일하다면 모니터를 호출 할 필요가 없으므로 이미 고정 된 내용을 통화 할 필요가 없으므로 설정이 중복됩니다. 'lockobject'가 다른 객체라면 Monitor.exit을 잠금 문으로 이동하지 않는 이유는 무엇입니까?