|
때때로 질답란에 글을 올리다보면 스스로 뭐가 문제였는지 정리가 되는 경우가 많은데 이번에도 그런 듯 합니다.
제가 썼던 구문이 대충 아래와 같습니다.
CriticalSection.Enter;
try
for i:=0 to RoomList.Count - 1 do
begin
if TDataModuleRoom(RoomList.Items[i]).RoomIndex = RoomIndex then
begin
{..................생략}
CriticalSection.Leave;
exit;
end;
end;
finally
CriticalSection.Leave;
end;
먼저 CriticalSection.Leave;를 하고 다시 CriticalSection.Leave; 구문이 실행되는 순간에 데드락에 빠진다는 걸 검색에서 찾아냈습니다.
제가 function에서 exit;를 하면 finally 구문이 실행이 되고 exit 되게 되고, 이 때 CriticalSection.Leave; 가 두 번 실행되면서 데드락에 빠져버린 걸로 생각됩니다.
exit;를 하면 왠지 finally 쪽 구문이 실행이 안 될 거 같아서, 혹시 모르니깐 한 번 더 해주자 싶어서 집어 넣은게 문제가 된 듯 하네요. C++에서는 return 해버렸을 때 어떻게 될지 한 번 테스트 해봐야겠습니다. 앞으로는 저런식으로 쓰지 말아야겠습니다. ^^
TThreadList에서도 마찬가지로 UnlockList가 두번 실행되면서 문제가 되는 듯 합니다.
ayh 님이 쓰신 글 :
: indy로 보드 게임 서버를 구축중입니다.
:
: 멀티쓰레드를 이용하는 작업은 해본적이 없는 터라서, (늘 서브 쓰레드 하나 만들어 쓰는 정도였죠.)
: 여러 쓰레드가 공유자원 특히 TList 객체에 접근하면서 문제가 생기더군요.
: TList에 넣어놓은 객체를 Delete후 Free하기만 하면 다른 부분에서 Access Violiation이 일어나는 걸 보고, 왜일까 생각해보니 다른 쓰레드가 해당 TList를 읽고 있을 때 발생할 수 있는 문제일 듯 하더군요.
:
: 해서 뒤져보니 나오는게, TCriticalSection을 사용하는 방법이었습니다.
: 의심되는 부분에 Enter, Leave를 써서 구축했습니다만, 어느 순간 얼어 붙더군요.
: 한 줄 한 줄 쫓아가보니, 두 객체에서 동시에 Enter 하는 순간 얼어 붙는 것 같더군요.
:
: 일단, 시간이 없어서 CriticlaSection의 사용은 유보하기로 하고 찾아보니, TThreadList가 있더군요.
: 이걸 쓰면 되겠다 싶어서 TList를 TThreadList로 모조리 바꾸고, LockList, UnlockList를 써서 구축했습니다만, 또 얼어붙더군요. 여기저기 뒤져보니깐, TTheradList의 LockList에서 TCriticlaSection을 사용한다는 코멘트가 나오더군요.
:
: 안되겠다 싶어서 이래저래 정리해서, TList의 객체를 삭제해야 될 때는 일단 해당 객체의 프로퍼티를 변경해 놓은 뒤 일정 기간에 한 번 씩 모아서 날려버리는 방식으로 프로그램을 돌아가게는 해 놨습니다만....
:
: 궁금한 건 TCriticalSection이 왜 얼어붙었을까 하는 점입니다.
: 원래 올바른 사용법이 있지 않을까 생각됩니다만....
:
: 그리고 CrticalSection 외에 멀티쓰레드에서 공유자원에 대한 접근을 제어하는 방법에 대해서 쓸만한 게 있으면 답변 주시면 감사드리겠니다.
: 좋은 하루 보내시구요~
|