2010-03-20 2 views
2

이것은 일종의 예외적 인 죽은 자물쇠인가요? 어떻게 피하는가?C++ Builder 2010 예외 데드락?

objlist에 저장된 연결된 클라이언트의 TIdContext 개체가있는 행을 아래에서 살펴보고 처리해야 할 때가 있습니다. 그러나 다른 스레드가 목록을 처리하는 동안 한 명의 사용자가 연결이 끊어진 경우 해제 된 TIdContext-> Data 개체에 대해 Access voilation을 얻습니다. 그래도 괜찮습니다. try/catch를 사용하지만 문제는 아래 줄에 몇 가지 종류가 있습니다. 죽은 자물쇠 및 프로세스가 멈추었습니다. 디버거를 부착하면 Access voilation을 다시 반복해서 표시하고, 그 예외적 인 dead lock 때문에 cpu coonsumption이 올라갑니다. 객체가 null가 아닌 경우

AnsiString UserID = ((Tmyobject*) ((TIdContext*) ObjList->Objects[i])->Data)->UserID;

은 내가, 내가 개체에 액세스하기 전에 확인할 수 있습니다 알고, 그것은 작동합니다 ..하지만 내 질문의 경우 한 번 파란 달의 ​​데이터 객체가 NULL 때 지점에서 해제 될 것입니다 검사가 수행되고 다음 줄에 다시 객체에 액세스 할 때 동일한 죽은 자물쇠가 생깁니 까 ???

이렇게 죽은 잠금 예외를 피하고 처리하는 방법은 무엇입니까? 여기

:005F07C0 System::AnsiStringBase::AnsiStringBase(this=:0285FCE0, src=????) 
:0040223F System::AnsiStringT<0>::AnsiStringT<0>(this=:0285FCE0, src=:00000008) 
:00457996 TSomeClass::SomeFunction(this=:009D8230, UserID={ }, DataSize={ },) 
:0047BFF1 __linkproc__ ThreadProc(Thread=:009561C0) 
:004AD00E __linkproc__ ThreadWrapper(Parameter=:009EAA30) 
:7c80b729 ; C:\WINDOWS\system32\kernel32.dll 

액세스 위반 처리하는 try/catch를 사용하지 마십시오

감사

+1

C++ 빌더가 악합니다! 미안, 나는 단지 그것을 말해야만했다 :]. – pajton

+1

BTW, try/catch는 액세스 위반이 아닌 C++ 예외를 잡기위한 것입니다. –

답변

2

을 helppppppppppppppppppppp하세요 ... 호출 스택입니다. 이것들은 Java NullPointerExceptions가 아니며 try/catch는 그들이 겪는 혼란을 처리 할 수 ​​없습니다. 대신 기본 버그를 수정하십시오.

deadlock은 둘 이상의 스레드가 영원히 붙어서 서로를 기다리는 경우입니다. 가지고있는 것은 race condition입니다. 한 스레드는 객체 목록을 업데이트하는 동안 다른 스레드는 객체 목록을 업데이트하고 첫 번째 스레드가 너무 빨리 완료되면 실수로 두 번째 스레드를 중단시킬 수 있습니다.

경합 조건을 처리하는 표준 방법은 경합 된 자원을 사용하는 모든 코드 주위에 어떤 종류의 잠금 장치를 두어 스레드를 정중하게 사용하는 대신 서로 경주하는 것입니다. 뮤텍스 (mutex)를 읽으십시오 : 이것은 간단한 동기화 프리미티브이지만 문제를 해결할만큼 강력합니다.

1

TIdTCPServer의 Contexts 속성은 스레드 안전 TThreadList이므로 LockList/UnlockList를 사용하여 서버를 변경하지 않고 활성 컨텍스트를 반복 할 수 있어야합니다. 별도의 목록을 유지 관리하는 경우 몇 가지 옵션이 있지만 목록에 추가/삭제하는 방법을 설명하는 코드를 게시해야합니다.

+0

예, 서버의 내장 클라이언트 목록을 사용하고 별도로 관리하지 마십시오. 연결/연결 해제 중에 쉽게 동기화되지 않을 수 있습니다. –