2011-01-24 7 views
0

다른 사람이이 문제를 본 적이 있는지 궁금합니다. 나는 정적으로 선언 된 객체를 고정하는 응용 프로그램이 방법이 :C# 뭔가 교착 상태의 명백한 버그를 다시 잠그려고 시도합니다.

lock(Group.IsisGroups) 
{ 
      do some stuff 
} 

할-일부-물건 다양한 물건과 내가 같은 잠금 장치를 잠금 시도라는 루틴 중 하나를 수행합니다. 스레드 교착 상태.

내 생각에이 문제는 내 리플렉션 사용과 관련이있다. 클래스 정의에서 찾아서 .Invoke()를 호출하여 메소드 호출을 중간에서 호출한다. 결과 호출 스택은 이것이다 :

[In a sleep, wait, or join] 
[External Code] 
ConsoleApplication2.exe!Isis.Group.doLookup(Isis.Address gaddr) Line 3774 + 0x13 bytes 
ConsoleApplication2.exe!Isis.ReliableSender.GotIncoming(byte type, Isis.Address gaddr, Isis.Address sender, int minStable, Isis.Msg m) Line 10179 + 0x9 bytes 
ConsoleApplication2.exe!Isis.ReliableSender.doReceive.AnonymousMethod14(byte type, byte code, int seqn, int truePayLoadLen, int PreFragLen, Isis.Address sender, Isis.Address dest, Isis.Address gaddr, int minStable, int FID, int Fn, int nF, byte[] buf) Line 3120 + 0x80 bytes 
[External Code] 
ConsoleApplication2.exe!Isis.Msg.doInvokeSingle(System.Delegate del, byte[] barray, System.Type[] types) Line 11582 + 0x10 bytes 
ConsoleApplication2.exe!Isis.Msg.InvokeFromBArray(byte[] barray, System.Delegate del) Line 11527 + 0xf bytes 
ConsoleApplication2.exe!Isis.ReliableSender.doReceive(object os, Isis.Group g) Line 10034 + 0x71 bytes 
ConsoleApplication2.exe!Isis.ReliableSender.Receive(Isis.Group g) Line 10013 + 0xe bytes 
ConsoleApplication2.exe!Isis.ReliableSender.StartGroupReader.AnonymousMethod__6(object o) Line 9097 + 0xc bytes 
[External Code] 

그래서 lock(Group.IsisGroups)에 대한 초기 호출 스택 ReliableSender.StartGroupReader하고 바닥 방법, doLookup 잠금을 호출하는 코드 교착 상태에 최고 방법이다. [External Code] 블록은 리플렉션 Invoke() 메서드를 호출 한 곳에서 발생하며 교착 상태가 발생하는 lock()으로 호출됩니다. 확실히 동일한 객체가 잠겨있는 등 (클래스가로드 될 때 객체가 정적으로 할당되고 유형이 List<Isis.Group>이고 항목을 추가 및 제거하는 동안 실제 List 객체는 그대로 유지됩니다.)

무엇이 발생할 수 있는지에 대한 제안 이?

+0

추 신 : 매번 발생하지 않습니다. 사실 그것은 내가 넣으면 일어난다.NET을 상당히 듀얼 프로세서 펜티엄에서 내 응용 프로그램의 몇 복사본을 시작하여 꽤 무거워. 이 모든 것이 최신 버전입니다. 그래서 나는 어떤 종류의 .NET 버그를 생각하고 있는가? –

+5

사람들이 .NET 버그라고 생각하는 경우의 99 %에서 의도하지 않은 코드 동작이 나타납니다. 이 경우에 무엇이 잘못되었는지는 확실치 않지만 .NET 버그라는 생각을 할인하는 경향이 있으므로 사용자 잘못이 아닙니다. – Chris

+0

다른 스레드를 살펴보면 그 중 하나가 잠금 객체를 가져 왔고 다른 스레드에 고정되어 있습니다. –

답변

0

좋아,이 열어두고 싶지 않아 내 "대답"은 다음과 같습니다. 첫째, (미안) Bengie와 Hans는 단지 충분히 이해할 수없는 것 같습니다. 재진입 잠금이 제대로 작동하지 않습니다. 둘째로, 저는 이것이 내 성찰을 사용하기 때문에 일어났다 고 생각합니다. 어떻게 든 락이 같은 thread에 의해 재 락되고있는 것을 인식하기 위해서 (때문에) 사용하는 컨텍스트 정보가 영향을 받고있는 것 같습니다.

초기 호출 중에 잠금을 유지하지 않도록 코드를 변경하여이 문제를 해결할 것입니다. 기본적으로, 나는이 자물쇠를 재진입하려고하지 않을 것입니다.

이 스레드를 실행하는 다른 사람들은 경고해야합니다. 내가 말할 수있는 한, .NET 버그 일 수있는 것이 발생했습니다. 그리고 도발하기가 그리 어렵지 않습니다.

1

내가 제대로이 글을 읽고 있습니까?

을 따라서 초기 호출 스택의 상단 방법에 (Group.IsisGroups)를 잠글 [...] 그리고 그것은에 자물쇠를 호출하는 코드의 교착 상태 아래쪽 메서드는 [...] 잠김을 일으키는 lock()에 있습니다. 확실히 동일한 객체가 잠겨 있습니다.

자물쇠가 어떻게 도움이되는지 보여주는 메소드의 일부 의사 코드가 있지만 읽은 내용에 따라 자물쇠에 같은 객체를 잠그는 것처럼 들립니다. 이

lock(ob1) 
{ 
    lock(ob1) 
    { 
    } 
} 

일어난 것처럼 내가 제대로 숙지 경우

, 그것은 소리하지만 당신은 자신의 확신 소리, 그래서 내가 그 잘못 읽고 있어요 있으리라 믿고있어.

어느 쪽이든, 잠금을 호출하는 메소드의 일부 의사 코드가 좋을 것입니다. : p

교착 상태는 개체를 "잘못된"순서로 잠그는 여러 메서드/스레드 때문에 발생합니다.

+0

그렇지 않습니다. 잠금은 동일한 스레드에서 재 입력됩니다. –

+0

나는 일반적으로 코드를 작성하지 않으므로 잊어 버렸다. 어쨌든 교착 상태가 발생하려면 최소한 두 개의 객체가 잠겨 있어야합니다. 다른 객체는 무엇이며 다른 메소드와 스레드는 잠금을 무엇이라고 부릅니까? – Bengie

+0

Bengie, 제 코드는 C#의 100K 라인입니다. 그래서 당신이 정말로 그것을 원할 것 같지 않습니다. 한스, 그게 다야. 이것은 제가 말하고자하는 바입니다 : 재입 통금 요청이 걸려 있습니다. Bengie, 나는이 물건에 대한 수업을 가르치고 교과서도 썼다. 나는 교착 상태의 원인을 안다. 일반적으로, 재진입 잠금 메서드가 중단되어서는 안됩니다. 따라서 .NET 시스템이 혼란스러워지고 이것이 재진입 요청임을 인식하지 못하게하는 원인이 있습니다. 그게 내 질문이야. 누구나이 기능을 어떻게 구현했는지, 특히 어떻게 속이는가? 분명히 그렇게하고 있기 때문에. –